【4858.com】全栈开辟,面向对象初识及编制程序观念

By admin in 4858.com on 2019年5月4日

面向对象

面向对象基础

4858.com,【递归、面向对象初识及编制程序观念】

一、递归

1、定义:

  在函数内部,能够调用别的函数。假使三个函数在个中调用本身自身,那些函数正是递归函数。

  (一)递归便是在进度或函数里调用自身;
  (贰)在应用递归战略时,必须有三个明显的递归甘休条件,称为递归出口。

 

1 def age(n):
2     if n ==1:   #条件判定
3         return 10  #返回一个结果
4     else:
5         return age(n-1)+2  #重复调用函数本身,系统会将运算的结果存放到栈,然后再依次的进行取值调用。
6 print(age(5))   #打印结果

 

 推行结果:1八

2、优缺点:  

  递归函数的独到之处是概念轻易,逻辑清晰。理论上,全部的递归函数都能够写成循环的主意,但循环的逻辑比不上递归清晰。

  递归的毛病:递归算法解题的周转功用异常低。在递归调用的进度在那之中系统为每一层的回来点、局部量等开采了栈来存款和储蓄。递归次数过多轻巧导致栈溢出等。

 

def func():
    print("*******")
    func()
func()

#执行结果
 [Previous line repeated 993 more times]
*******
  File "F:/py_fullstack_s4/day26/递归.py", line 8, in func
*******
    print("*******")
*******
RecursionError: maximum recursion depth exceeded while calling a Python object

 

叁、递归编制程序的注意点:

  壹. 须求有二个明显的告竣条件。

  二. 老是进入更加深一层递归时,难题规模相比较上次递归都应负有削减。

  三.递归功能不高,递归档案的次序过多会招致栈溢出(在Computer中,函数调用是经过栈(stack)那种数据结构落成的,每当进入四个函数调用,栈就能够加1层栈帧,每当函数再次回到,栈就能减1层栈帧。由于栈的高低不是最最的,所以,递归调用的次数过多,会招致栈溢出)。

四、此处引出3个新的知识点:二分法

  二分法,是1种高效找寻的措施,时间复杂度低,逻辑轻巧易懂,总的来说正是接踵而至 蜂拥而至的除以2除以2…

  他珍视利用于不改变系列中,原理是历次搜寻都将原连串折半,逐步压缩查找范围的一种算法。应用于递归,循环之中,直到找到结果。

 

#运用 递归 和 二分法 的运算方式,查找列表中的某个值
data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
num = int(input("please input your want to find number:"))
def search(num,data):
    if len(data) > 1:      #排除列表分割,仅剩一个元素的情况
         #二分法#
        a = int(len(data)//2)   #将计算列表的长度,除以2  取整数
        mid_value = data[a]     #取当前中间的值
        if num > mid_value:     #要找的值 大于 中间的值
            data = data[a:]     #将原列表从中间值往后,取出来,构建一个新列表
            search(num,data)    #递归判断
        elif num < mid_value:   #要找的值 小于 中间的值
            data = data[:a]     #将原列表开始到中间值,取出来,构建一个新列表
            search(num,data)    #递归判断
        else:                   #正好是这个值
            print("find it!!",num)
            return          #打印
    else:                         #判断列表分割,仅剩一个元素的情况
        if data[0] == num:
            print('find it!! %s'%data[0])
        else:                     #列表中没有这个值
            print('not this num %s'%num)

search(num,data)

#执行结果:
please input your want to find number:18
find it!! 18

 

 

二、面向对象的主次设计

壹、前提铺垫:

  python中全体皆为对象,python
三集合了类与类型的概念,类型正是类。例如:int,str,list,等等……

  编制程序语言中,是先有了类,然后再发生一个个对象。而现实生活中恰恰相反。

  明显一点:面向对象编制程序是壹种编制程序格局,此编制程序方式的机能须求使用 “类” 和 “对象” 来达成,所以,面向对象编制程序其实就是对 “类” 和 “对象”
的使用

  类就是3个模板,模板里可以分包成立多少个函数,函数里实现自定义的作用

  对象则是基于模板成立的实例,通超过实际例(对象)能够试行类中定义的函数

2、语法:

  一)成立类:class是不能缺少字,表示类 class *** #创建类
  2)创造对象:类名称后加括号 将结果赋给二个变量 就可以 x = ***()
#成立对象

 

 

 1 class hello:  #任意定义一个类
 2     camp = 'hello world'
 3     def f(self):
 4         print("f")
 5 h = hello() # 类实例化
 6 print(h) #打印
 7 
 8 #执行结果:
 9 
10 <__main__.hello object at 0x00000000026C9630>

 

三、类与对象

壹)什么是目的:
  以娱乐比如:LOL,每种游戏用户选三个两肋插刀,每一个铁汉都有友好的特点和和才具,特征即数据属性,本事即方法属性,特征与才能的结合体就2个目标。

二)什么是类:
  从一组对象中领到对象联手的
特征,本事,构成贰个类。类也是特点与才能的结合体
,特征即数据同时是持有目的共享的数量,技术即函数属性并且是独具目标共享的函数属性。 

  ①优点:化解了程序的扩张性,对有个别对象开始展览退换,会及时反映到一切系统中
  【4858.com】全栈开辟,面向对象初识及编制程序观念。②缺点:可控性差,无法预测最后的结果。
  面向对象的主次设计并不是程序全体。对于软件品质来讲,面向对象的次第设计只是用来化解增添性的标题。

def 或是 class 都以在概念叁个函数名。class 定义 类    camp 阵营   
attack(self) 技术    nickname别称    init 起始,初阶

三)怎样利用类:
 一、实例化

  类的实例化就能够时有发生1个实例(对象)。
能够清楚为类加()把虚拟的东西实例化,获得具体存在的值,叫做类的实例化。

 

class
Garen: #概念贰个类

    camp = 'Demacia'
def attack(self):
    print('attack')
g1 = Garen() #类的实例化,产生一个对象,可以调用类内包括的所有特征(共性)。
print(g1)  #打印

#执行结果:
<__main__.Garen object at 0x00000000028C9CC0>

 

 2、类通过.(点)的点子引用特征(类的变量)和才干(类的函数(类内部依然定义的函数,调用的话依旧供给传入参数))

 

class Garen:
    camp='Demacia'
    def attack(self):
        print('attack')
print(Garen.camp)  #查看camp
print(Garen.attack)   #打印数据类型
Garen.attack('nihao') #由于是调用有参函数,需要传值

#执行结果:
Demacia
<function Garen.attack at 0x000000000229C950>
attack

 

2、目的之间也有不一样,及除了同性也有特色。比方别称!

 

class Garen:
    camp='Demacia'

    def __init__(self,nickname):
        self.nick=nickname  #给实例自己定义一个别名,由外部传入 #g1.nick = '草丛伦'
    def attack(self,enemy):
        # print('---------->',self.nick) #g1.nick
        print('%s attack %s' %(self.nick,enemy))


g1=Garen('草丛伦') #类实例化,类Garen触发调用_init_ #Garen._init_(self,'NB')
g2=Garen('刘下')
print(g1.nick)
g1.attack('alex')

#执行结果:
草丛伦
草丛伦 attack alex

 

self 指自己。

在意:类的实例化就能够自动触发类内_init_函数的实施。

三、怎么调用类的风味与才具

留意:类与目的之间的绑定方法。调用绑定方法,python
会自动传值,会将调用者本人作为参数字传送给self,第贰值。

print(gi.attack) #调用绑定方法,类绑定给g壹
print(Garen.attack) #函数

 

class Garen:
    camp='Demacia'

    def __init__(self,nickname):
        self.nick=nickname  #给实例自己定义一个别名,由外部传入 #g1.nick = '草丛伦'
    def attack(self,enemy):
        # print('---------->',self.nick) #g1.nick
        print('%s attack %s' %(self.nick,enemy))


g1=Garen('草丛伦') #类实例化,类Garen触发调用_init_ #Garen._init_(self,'NB')
g2=Garen('刘下')

print(g1.nick)  #昵称
print(g1.camp)  #阵营
print(g1.attack)  #打印 查看绑定方法
print(Garen.attack)  # 打印 函数

#执行结果:
草丛伦
Demacia
<bound method Garen.attack of <__main__.Garen object at 0x0000000002299D68>>
<function Garen.attack at 0x000000000229C9D8>

 

Garen.attack(参数)# 调用的是函数,须求传参
g1.attack(‘alex’) #self = g1;enemy =
‘alex’假使函数有多个值,就在赋值的时候,传入别的的参数。

print(g1.nick)

设即使目标触发的,调用的时候就能活动给调用的函数字传送值,将自己传到首个参数self。假使函数有四个值,就在赋值的时候,对应的突然不见了别的的参数。

 

class Garen:
    camp='Demacia'

    def __init__(self,nickname):
        self.nick=nickname  #给实例自己定义一个别名,由外部传入 #g1.nick = '草丛伦'
    def attack(self,enemy):
        # print('---------->',self.nick) #g1.nick
        print('%s attack %s' %(self.nick,enemy))


g1=Garen('草丛伦') #类实例化,类Garen触发调用_init_ #Garen._init_(self,'NB')
g2=Garen('刘下')
print(g2.nick)
print(g2.camp)

#执行结果:
刘下
Demacia

 

三、总结:
一、类:1:实例化,二:引用名字(类名.变量名,类名.函数名)
获得2个内部存款和储蓄器地址,加()就能够运营。

2、实例(对象):引用名字(实例名.类的变量,实例名.绑定方法,实例名.实例本人的变量名)

3、类:
 优点:消除了程序的扩张性,对某些对象开展更改,会立刻反映到全方位系统中
 缺点:可控性差,不可能预测最后的结果。
  面向对象的先后设计并不是整个。对于软件品质来讲,面向对象的主次设计只是用来缓和扩张性的主题材料。

在python中,用变量表示特征,用函数表示方法,因此类是变量与函数的结合体,对象是变量与方法(指向类的函数)的结合体

4、类属性:特征(变量)和方法(函数)

5、类有二种艺术:一.类的实例化;二.属性引用
  1.实例化:
    类名加括号正是实例化,会自行触发__init__函数的周转,能够用它来为各样实例定制本身的性状
  2.属性引用:
    类名.方法

陆、对象也叫坚实例

  对象的性质:对象自笔者就自有特点(变量)

  对象的唯有1种用法:属性引用

七、类的名目空间和对象的名号空间

创立一个类,就能够创造2个类的名称空间,存放类中定义的性质:特征(数据)和办法(函数)
创造1个对象,及类的实例化,就能创立贰个类的称谓空间,存放对象的习性。

在意:对象正是类的实例化,类成就实例化的操作就早已将类的主意绑定到目的上,对象调用方法会未来协和的名称空间去找,找不到会去类的名目空间去找,再找不到位抛异常。它不会去找全局的定义。

查看类的称谓空间
类名._dict_

翻看对象的名目空间
对象名._dict_

绑定方法的大目的在于于‘绑定’,唯一绑定到1个规定的靶子

能够调用:查
print(Garen.camp) #查

能够更换:改
Garen.camp=’aaaaaa’ #改
print(Garen.camp)

能够去除: 删
del Garen.camp #删除
print(Garen.camp)

能够拉长: 增
Garen.x=1 #日增风味
print(Garen.x)

关于目的(实例)

能够调用: 查
g1=Garen(‘alex’)
print(g1.nick) #查

能够改造: 改
g1.nick=’asb’ #改
print(g1.nick)

能够去除: 删
del g1.nick
print(g1.nick) #删

能够扩展: 增
g1.sex=’female’
print(g1.sex) #增加

四、面向对象的软件开荒:

分为5部:

一、面向对象分析(object
oriented analysis,OOA):

出品COO应用切磋市镇,侦察,明显软件的用处和使用场景。
2、面向对象设计(object
oriented design,OOD):

依赖供给,对每一片段举办实际的安插性,比如:类的布署
三、面向对象编制程序(object
oriented programming,OOP):

将设计编程成代码
四、面向对象测试(object
oriented test,OOT):

对写好的代码实行测试,发掘错误并勘误。面向对象的测试是用面向对象的主意举办测试,以类为测试的中坚单元。
5、面向对象维护(object
oriented soft maintenance,OOSM):

缓和用户使用产品进程中出现的标题,或是扩充新的效果。

面向对象编程观念:
1、设计的时候,一定要确定利用场景

二、由对象分析定义类的时候,找不到共同特征和技术不用强求

一、面向对象

4858.com 14858.com 2

面向过程编程
    核心是”过程“二字,过程指的是解决问题的步骤,即先干什么再干什么
    基于该思想编写程序就好比在编写一条流水线,是一种机械式的思维方式

    优点:复杂的问题流程化、进而简单化
    缺点:可扩展性差

面向进度

亮点:化解程序的扩张性,可扩充性强

缺陷:壹.编制程序的复杂度高于面向进程

     二.可控性差,十分小概像面向进程相同精准的猜想难题的管理流程与结果

应用场景:要求日常转移的软件,一般须求的浮动都聚集在用户层,网络使用,公司内部软件,游戏等都是面向对象的先后设计大显身手的好地方

一、面向对象编程与面向进程编制程序

一、面向进度编制程序观念

该思虑主导是经过,指的是杀鸡取蛋难题的步调,即先干什么再干什么。基于该寻思编制程序就像是一条流水生产线,是1种机械式的考虑方法

优点:复杂难点轻便化,流程化

症结:可扩张性差

二、面向对象编制程序观念

该思量主导是目的,对象是特色与技艺的结合体。任何事物都足以是目的

可取:可扩张性强

症结:编制程序的复杂度高于面向进度编程

编制程序范式

所谓的面向对象编制程序,指的正是①种编制程序范式,那么什么样是编制程序范式呢?即是遵从某种语法风格加上数据结构加上算法来编写程序

  • 数据结构:列表、字典、集结
  • 算法:编写程序的逻辑恐怕解决难题的流程

叁个主次是技术员为了获取二个任务结果而编辑的1组命令的聚集,正所谓跳跳大陆通奥克兰,达成三个职责的措施有很多样分歧的措施,对那么些差异的编制程序方式的特点开展归咎总计得出来的编制程序格局连串,即为编制程序范式。

分歧的编制程序范式本质上代表对各类别型的天职使用的例外的缓慢解决难点的笔触,大多数言语只援助一种编制程序范式,当然也某个语言可以同时帮忙各样编程范式。二种最根本的编制程序范式分别是面向进度编程面向对象编制程序

贰、类和目的

对象是特点与才能的结合体,那类正是1层层对象一样的特征与技艺的结合体

 

类:具备同等属性特征的壹类东西

对象:具体的某壹东西

 

在现实世界中:先有目的,再有类

在程序中:务必保管:先定义类,后调用类来发出对象

 

程序中模板

#1. 在程序中特征用变量标识,技能用函数标识
#2. 因而类中最常见的无非是:变量和函数的定义
#3. 在定义类的阶段会立刻执行类体内的代码,然后将产生的名字存放于类名称空间中
#4. __init__  不能有返回值
class 类名:
    def __init__(self,参数1,参数2):
        self.对象的属性1 = 参数1
        self.对象的属性2 = 参数2

    def 方法名(self):pass

    def 方法名2(self):pass

对象名 = 类名(1,2)  #对象就是实例,代表一个具体的东西
                  #类名() : 类名+括号就是实例化一个类,相当于调用了__init__方法
                  #括号里传参数,参数不需要传self,其他与init中的形参一一对应
                  #结果返回一个对象
对象名.对象的属性1   #查看对象的属性,直接用 对象名.属性名 即可
对象名.方法名()     #调用类中的方法,直接用 对象名.方法名() 即可

注意点:

  1. 类中得以有任性python代码,那么些代码在类定义阶段便会举办
  2. 故而会发出新的名目空间,用来存放类的变量名与函数名,能够通过 类名.__dict__查看
  3. 对此杰出类来讲大家能够通过该字典操作类名称空间的名字(新式类有限量),但python为大家提供尤其的.语法
  4. 点是访问属性的语法,类中定义的名字,都以类的属性

python为类内置的越发质量

 

类名.__name__# 类的名字(字符串)
类名.__doc__# 类的文档字符串
类名.__base__# 类的第一个父类(在讲继承时会讲)
类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)
类名.__dict__# 类的字典属性
类名.__module__# 类定义所在的模块
类名.__class__# 实例对应的类(仅新式类中)

 

python类定义阶段,每七个类的艺术必须出示定义self

ps:def  __init__(self):   这句话可以写也可以不写,只要有参数参进来的时候就必须得写

  def  方法名(self):这里的self必须得写

二、类

1、对象是特色与技能的结合体,而类是一多级对象同样的表征与才能的结合体

贰、类与目标 的分别
(一)对象是具体存在的事物,而目标是虚幻的概念

(2)在不一致角度总计出来的类与对象是不一致的

三、在具体世界,先有对象,然后有类;而在程序中,先有类,然后调用类发生对象

4858.com 34858.com 4

1 stu1
2     school:'oldboy'
3     name:'zs'
4     age:18
5 
6 stu2
7     school:'oldboy'
8     name:'ls'
9     age:34

对象

4858.com 54858.com 6

1 class OldboyStudent:
2     school = 'oldboy'
3 
4     def study(self):
5         print('dddd')
6         return 'dddd'

面向进程编制程序

面向进程编制程序,宗旨就是经过贰字,进度指的是涸泽而渔难题的步子,正是先干什么,然后干什么,最终怎么?实际上就一定于统筹了一条流水生产线,就是机械式的讨论方法,把二个大难点拆分成若干个小意思,然后3个个小题目再细化,然后再把这个小标题结合起来,就缓慢解决了多个大标题。

下面来看上面向经过的编制程序,让用户输入注册新闻:

import json
import re
def interactive():  # 接收用户输入
 name = input('>>>').strip()
 pwd = input('>>').strip()
 return {
        'name':name,
        'pwd':pwd
 }
def check(user_info):  # 检测
 is_valid = True
 if len(user_info['name']) == 0:
  print('用户名不能为空!')
  is_valid = False
 if len(user_info['pwd']) < 6:
  print('密码不能少于6位!')
  is_valid = False
 return {
        'is_valid':is_valid,
        'user_info':user_info
 }
def register(check_info):  # 写入数据库中
 if check_info['is_valid']:  # 如果为真
  with open('db.json','w',encoding='utf-8') as f:
   json.dump(check_info['user_info'],f)

def main():  # 主函数
 user_info = interactive()
 check_info = check(user_info)
 register(check_info)

if __name__ == '__main__':
 main()

这就是说这段程序的运营结果就是唤醒输入用户名和密码,然后对用户名和密码举办检查评定,假诺符合规则,那么就将写入数据库中。

那正是说此时,若是本人想让用户再登记音信的时候,再增多邮箱,代码是怎么写的吗?

import json
import re
def interactive():  # 接收用户输入
 name = input('>>>').strip()
 pwd = input('>>').strip()
    email = input('>>').strip()
 return {
        'name':name,
        'pwd':pwd,
        'email':email
 }
def check(user_info):  # 检测
 is_valid = True
 if len(user_info['name']) == 0:
  print('用户名不能为空!')
  is_valid = False
 if len(user_info['pwd']) < 6:
  print('密码不能少于6位!')
  is_valid = False
     if not re.search(r'@.*?\.com$',user_info['email']):
     print('邮箱格式不合法!')
        is_valid = False
 return {
        'is_valid':is_valid,
        'user_info':user_info
 }
def register(check_info):  # 写入数据库中
 if check_info['is_valid']:  # 如果为真
  with open('db.json','w',encoding='utf-8') as f:
   json.dump(check_info['user_info'],f)

def main():  # 主函数
 user_info = interactive()
 check_info = check(user_info)
 register(check_info)

if __name__ == '__main__':
 main()

假若大家还要加上来自国家、性别、年龄那个音信,那整个代码流程不都要三番7次修改吗?那么大家今后就能够观望面向进度的优缺点了:

优点:把纷纭的主题材料流程化,进而轻易化

症结:可扩张性差

应用场景:自动安插、系统监察和控制脚本

3、类的实例化、对象的操作

类实例化:调用类产生对象的进程称为类的实例化,实例化的结果是多个对象,或称为1个实例

# 定义一个People类
class People:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

    def run(self):
        print('%s is running' %self.name)


# 实例化一个对象  obj
obj = People('fixd',18,'male')

实例化做的三件事:

  1. 首发生二个空对象
  2. 电动触发类内部的__init__函数的奉行
  3. 将空对象,以及调用类括号内传出的参数,一齐传给__init__,为目的定制独有的性质

翻开对象的称谓空间(__dict__)

print(obj.__dict__)

③、类的应用

  1. 类精神就是贰个名号空间,恐怕说是三个用来存放变量与函数的容器 , 能够用
    __dict__来访问名称空间中的名称
    2.用途

(一)类的用处之一正是作为名称空间从其内部取盛名字来采纳,(类名.属性,能够对类中的属性进行增加和删除改查)
(二)类的用途之2是调用类来产生对象

3.调用类发生对象的进度:

(一)创设三个空对象

(贰)将值传入并赋初步值 

#1.定义类
class OldboyStudent:
    #相同的特征
    school = 'oldboy'

    #相同的技能
    def choose_course(self):
        print('choosing course')

# 但其实类体中是可以存在任意python代码的
# 类体代码会在类定义阶段立即执行,会产生一个类名称空间,用来将类体代码执行过程中产生的名字都丢进去,查看方式如下
print(OldboyStudent.__dict__) # 查看类的名称空间
print(OldboyStudent.school) print(OldboyStudent.__dict__['school'])
print(OldboyStudent.choose_course)
OldboyStudent.school='OLDBOY' OldboyStudent.__dict__['school']='OLDBOY'
OldboyStudent.country='China' OldboyStudent.__dict__['country']='China'
del OldboyStudent.country # del OldboyStudent.__dict__['country']
print(OldboyStudent.__dict__)
#2. 后调用类来产生对象

面向对象编程

面向对象编制程序,宗旨正是对象贰字,正是站在上帝的见解:全数存在的事物都以i对象

举个例证表明:在西游记中,释迦牟尼便是上帝,他想要消除的难点就是什么样把经书传入大唐,假如是面向进程来讲,释迦牟尼佛就要想那条路要怎么走,境遇职业的时候理应怎么管理,正是要把取经的进度整整都要考虑到,然则换来面向对象呢?他找来了唐玄奘、孙悟空等人,妖鬼怪怪,一大堆佛祖起头了取经之路…

本身和小明的性状都是目标,大家的性状都是有鼻子有眼睛、多只手两条腿,技能正是用餐、学习、睡觉,所以大家得以被号称对象。

缘何您不会感到您前面的台式机不是孙猴子呢?因为台式机有显示屏、键盘、鼠标,而齐天大圣有毛脸雷神嘴、会七十二变、有火眼金晶,所以你不会如此以为。

所谓的靶子:便是特点和才干的结合体

面向进程:设计流程化

面向过程:站在上帝的见地来模拟世界

​ 优点:可扩大性高

​ 缺点:编程复杂度高

​ 应用场景:用户须求常常改造:互连网使用,游戏,集团内部选拔

4、对象的操作

print(obj.name) #查看 属性name的值
obj.education='哈佛'  # 添加属性
del obj.name    # 删除属性
obj.age=19      # 修改属性值
print(obj.__dict__) # 查看实例化对象的名称空间

4、对象的运用

一、调用类的经过称之为类的实例化,调用类的回来值称之为类的1个对象/实例

二、为对象定制自身独有的特点,利用__init__方法

3、__init__办法在实例化时就为对象起先自身独有的风味,不能有重临值,而且会将目标活动传进类

 1 class OldboyStudent:
 2     #相同的特征
 3     school = 'oldboy'
 4 
 5     def __init__(self, name, age, sex):
 6         self.name = name    #stu1.name='李铁蛋'
 7         self.age = age           #stu1.age=18
 8         self.sex = sex           #stu1.sex='male'
 9 
10     #相同的技能
11     def choose_course(self):
12         print('choosing course')
13 
14 
15 # 调用类,产生对象
16 stu1=OldboyStudent('李铁蛋',18,'male')

面向对象程序设计

在软件品质属性上,费用、品质、安全性、可扩张性都以必须要有的,不过可扩充性占的比例依旧比较高的。

五、对象属性的搜索顺序

先找目的本人的名称空间———–>>类的名称空间

1、类的数码属性:是给目标用的,而且间接共享给全部目的的用的,内部存款和储蓄器地址都一致

4858.com 74858.com 8

# 定义一个People类
class People:
    country = 'China'
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def run(self):
        print('%s is running' % self.name)

people1 = People('fixd01', 18, 'male')
people2 = People('fixd02', 25, 'male')
people3 = People('fixd03', 30, 'male')

# 实例化三个对象
people1 = People('fixd01',18,'male')
people2 = People('fixd02',25,'male')
people3 = People('fixd03',30,'male')

# 查看country属性对应的 内存地址
print(id(People.country))
print(id(people1.country))
print(id(people2.country))
print(id(people2.country))



##############################
#结果:id  值都是相同的
#140238495738936
#140238495738936
#140238495738936
#140238495738936

类的数据属性是共享的

贰、类的函数属性:是给目的调用,可是绑定给目的的用的,绑定到区别的对象便是见仁见智的绑定方法

4858.com 94858.com 10

# 定义一个People类
class People:
    country = 'China'

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def run(self):
        print('%s is running' % self.name)

# 实例化三个对象
people1 = People('fixd01', 18, 'male')
people2 = People('fixd02', 25, 'male')
people3 = People('fixd03', 30, 'male')

# 调用 run()方法
people1.run()
people2.run()
people3.run()

# 查看run 的内存地址
print(people1.run)
print(people2.run)
print(people3.run)
#

##############################
#结果: 内存地址不同
fixd01 is running
fixd02 is running
fixd03 is running


##############################
#结果: 内存地址不同
<bound method People.run of <__main__.People object at 0x7f1c487e3978>>
<bound method People.run of <__main__.People object at 0x7f1c487e39e8>>
<bound method People.run of <__main__.People object at 0x7f1c487e3a20>>

类的函数(绑定方法)

 

五、属性(变量和函数)查找

一、先从目的自个儿的名号空间找,未有则去所属的类中找

二、类中定义的变量是兼具目的共享的,对象足以来用,类也足以来使用,类一旦改变本人的多寡属性的值,全体的对象都能感知到

4858.com 114858.com 12

 1 class OldboyStudent:
 2     school = 'oldboy'
 3     count=0
 4 
 5     def __init__(obj, name, age, sex):
 6         OldboyStudent.count+=1
 7         obj.name = name
 8         obj.age = age
 9         obj.sex = sex
10 
11     def choose_course(self):
12         print('choosing course')
13 
14 
15 
16 stu1=OldboyStudent('李铁蛋',18,'male')
17 stu2=OldboyStudent('赵钢弹',38,'female')
18 stu3=OldboyStudent('刘银弹',28,'male')
19 print(stu1.count)         # 3
20 print(stu2.count)         # 3
21 print(stu3.count)         # 3
22 print(OldboyStudent.count)        # 3

创立对象个数计算

类即体系、系列,是面向对象设计最器重的概念。刚刚大家精通对象是特点和技能的结合体,那么类就是1层层对象一般的特性与技巧的结合体

那正是说难题来了,先有的一个个实际存在的对象(举例一个现实存在的人),依旧先有人类那一个定义,这些难点亟待分二种情形去看

  • 在切实可行世界中,料定是先有的对象,然后才有的类
世界上肯定是先出现各种各样的实际存在的物体,然后随着人类文明的发展,人类站在不同的角度总结出了不同的种类,比如人类、动物类、植物类等概念。也就说,对象是具体的存在,而类仅仅只是一个概念,并不真实存在,比如你无法告诉我人类具体指的是哪一个人。
  • 在先后中,务必先确定保障先定义类,后产生对象
与函数的使用是类似的:先定义函数,后调用函数,类也是一样的:在程序中需要先定义类,后调用类。不一样的是:调用函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象

6、绑定方法的格外之处

  1. 绑定给何人就应当由哪个人来调用
  2. 何人来调用就能够把什么人当做第一个参数字传送入

6、绑定方法

一、类中属性改造

类中定义的变量是类的数目属性,类能够用,对象也能够用,我们都针对同三个内存地址,类变量值一旦改换全部目标都随着变
类中定义的函数是类的函数属性,类能够用,类来调用正是3个一般性的函数,但其实类中定义的函数是给目标用的,而且是绑定给目的用的

二、类的函数: 该传多少个参数就传多少个

 1 class OldboyStudent:
 2     school = 'oldboy'
 3 
 4     def __init__(self, name, age, sex):
 5         self.name = name
 6         self.age = age
 7         self.sex = sex
 8 
 9     def choose_course(self,x):
10         print('%s choosing course' %self.name)
11 
12 
13 OldboyStudent.choose_course(stu1,1)

3、绑定方法

绑定给何人就应有由什么人来调用,哪个人来调用就能够将谁当做第一个参数(self)自动传入

class OldboyStudent:
     school = 'oldboy'

     def __init__(self, name, age, sex):
         self.name = name
         self.age = age
         self.sex = sex

     def choose_course(self):
         print('%s choosing course' %self.name)


stu1.choose_course('张三',18,'male')

 

定义类

依据地点步骤,大家来先定义八个类(站在母校的角度,大家都是学生)

  • 在现实世界中,先有目的,然后才有的对象
对象1:李坦克
 特征: 
  学校:zhcpt
  姓名:李坦克
  性别:男
  年龄:18
 技能:
  学习
  吃饭
  睡觉
对象2:王大炮
 特征:
  学校:zhcpt
  姓名:王大炮
  性别:男
  年龄:23
 技能:
  学习
  吃饭
  睡觉
对象3:张小丽
 特征:
  学校:zhcpt
  姓名:张小丽
  性别:女
  年龄:16
 技能:
  学习
  吃饭
  睡觉

现实中的学生类:
 相似的特征:
  学校 = zhcpt
 相似的技能:
  学习
  吃饭
  睡觉
  • 在程序中,务必保管:先定义类,然后使用类(发生对象)
# 在python中程序中的类用class关键字定义。而在程序中特征用变量标识,技能用函数表示,因而类中最常见的无非是:变量和函数的定义

# 先定义类
class zhcptStundet:
    school = 'zhcpt'  # 相同的特征
    def learn(self):  # 相同的属性
        print('is learning')
    def eat(self):
        print('is eatting')
    def sleep(self):
        print('is sleeping')

# 后产生对象
zhcptStudent()

发出二个对象,不是去实践类体,而是实行这么些类体后会获得三个重返值。那些重回值正是目的,在那一个进程中也被称呼实例化。所以应当是这么的:

stu1 = zhcptStudent()  # 类的实例化
print(stu1)  # <__main__.zhcptStundet object at 0x0000013557F00438>

print(stu1)则是打印zhcptStudent这个类产生的对象,是这个对象的内存地址

注意:

  • 类中可以有私行的python代码,这个代码在类定义阶段便会推行,因此会生出新的名称空间,用来存放类的变量名和函数,能够因而zhcptStundet.__dict__措施去查看
  • 类中定义的名字,都以类的质量,点是造访属性的语法
  • 对此优秀类来讲,我们能够通过该字典去操作类名称空间的名字,但最新类有限定
# 定义类
class zhcptStudent:
    school = 'zhcpt'  # 类的数据属性,定义新的名字,新的命名空间
    def learn(self):  # 类的函数属性,定义了函数,产生了函数局部名称空间,把函数内部定义的名字放进去
        print('is learning')
    def eat(self):
        print('is eatting')
    def sleep(self):
        print('is sleeping')
    print('----------run-----------')

# 查看类的名称空间
print(zhcptStudent.__init__)

我们恰好说类在概念阶段时候便会推行,由此会时有产生新的称呼空间,用来存放类的变量名和函数,能够因此措施去查看,运营结果为:

----------run-----------
{'__module__': '__main__', 'school': 'zhcpt', 'learn': <function zhcptStundet.learn at 0x0000022B584A0C80>, 'eat': <function zhcptStundet.eat at 0x0000022B584A0D08>, 'sleep': <function zhcptStundet.sleep at 0x0000022B584C90D0>, '__dict__': <attribute '__dict__' of 'zhcptStundet' objects>, '__weakref__': <attribute '__weakref__' of 'zhcptStundet' objects>, '__doc__': None}

从而类和函数就有了差异:函数在概念完结以往不调用的话,那么那段函数就不会实行,而类在概念阶段就能实行

针对属性,python提供了专门的性格访问语法,以往大家来查阅访问下变量属性的值、函数属性的值

print(zhcptStudent.school)
print(zhcptStudent.learn)

运行结果为:

zhcpt
<function zhcptStudent.learn at 0x000001D94F020C80>  # 打印的是这个类下的learn函数内存地址

刚刚大家说,能够透过字典的格局去操作类名称空间的名字,让大家来看一下:

print(zhcptStudent.__dict__['school'])
print(zhcptStudent.__dict__['learn'])

运行结果和下边是如出1辙的:

zhcpt
<function zhcptStudent.learn at 0x0000023D2EAB0C80>

实质上,咱们很早在此以前就接触过类了,还记得大家事先学过了list、dict吗?记得time吗?

In [2]: print(list)
<class 'list'>

In [3]: print(dict)
<class 'dict'>

# time本身也是一个类
import time
time.sleep  # 其中time是类,sleep是类里定义的函数属性

七、一切皆对象

在python3中联合了类与项目标定义,类即类型。

 

类的操作

class zhcptStudent:
    school = 'zhcpt'  
    def learn(self):  
        print('is learning')
    def eat(self):
        print('is eatting')
    def sleep(self):
        print('is sleeping')
    print('----------run-----------')

增加

zhcptStudent.country = 'CN'
print(zhcptStudent.__dict__)
print(zhcptStudent.country)

# 运行结果
----------run-----------
{'__module__': '__main__', 'school': 'zhcpt', 'learn': <function zhcptStudent.learn at 0x00000233B8D10C80>, 'eat': <function zhcptStudent.eat at 0x00000233B8D10D08>, 'sleep': <function zhcptStudent.sleep at 0x00000233B8D390D0>, '__dict__': <attribute '__dict__' of 'zhcptStudent' objects>, '__weakref__': <attribute '__weakref__' of 'zhcptStudent' objects>, '__doc__': None, 'country': 'CN'}
CN

删除

del zhcptStudent.country
print(zhcptStudent.__dict__)

# 运行结果,已经找不到country这个k了
{'__module__': '__main__', 'school': 'zhcpt', 'learn': <function zhcptStudent.learn at 0x000001EEF1380C80>, 'eat': <function zhcptStudent.eat at 0x000001EEF1380D08>, 'sleep': <function zhcptStudent.sleep at 0x000001EEF13A90D0>, '__dict__': <attribute '__dict__' of 'zhcptStudent' objects>, '__weakref__': <attribute '__weakref__' of 'zhcptStudent' objects>, '__doc__': None}

修改

zhcptStudent.school = '珠海城市职业技术学院'
print(zhcptStudent.school)

运行结果:
珠海城市职业技术学院

初步化方法

首先先定义3个zhcptStudent类

class zhcptStudent:
    school = 'zhcpt'  # 相同的特征
    def learn(self):  # 相同的属性
        print('is learning')
    def eat(self):
        print('is eatting')
    def sleep(self):
        print('is sleeping')
    print('----------run-----------')

stu1 = zhcptStudent()
stu2 = zhcptStudent()
stu1.learn()
stu2.eat()

# 运行结果是
----------run-----------
is learning
is eatting

上边说过,类是装有1层层对象一般的本事和品质的结合体,对象特征与本领的结合体

那么,实例化的目的,总有两样的地点,例如李坦克是男的,而张小丽是女的,所以我们须要为对象定制对象自个儿独有的性状:

class Student:
    school = 'zhcpt'
    def __init__(self,name,age,sex):
        self.Name = name
        self.Age = age
        self.Sex = sex
    def learn(self):
        print('is learning')
    def eat(self):
        print('is eatting')

stu1 = Student()  # TypeError: __init__() missing 3 required positional arguments: 'name', 'age', and 'sex'

今年就能够报错,提醒贫乏多少个参数,然则大家却绝非调用__init__主意,为啥吧?因为python会自动调用,何时会调用呢?创立对象、调用类、实例化的时候就能调用。

stu1 = Student('李坦克',18,'女')

那么这个时候,就相当于把 ('李坦克','女',18) 三个参数传递进去了,即
        self.Name = '李坦克'
        self.Age = 18
        self.Sex = '女'

加上__init__方法后实例化的步骤:

​ 一.头阵生二个空对象

​ 2.触发Student.init(stu1,’李坦克’,18,’女’)

怎么触发就能把参数字传送递进去吧?

print(Student.__init__)

结果为:
<function Student.__init__ at 0x000001CFC9AE0C80>  # 原来__init__方法是一个函数,那么函数就必须要传入参数

类的操作

class Student:
    school = 'zhcpt'
    def __init__(self,name,age,sex):
        self.Name = name
        self.Age = age
        self.Sex = sex
    def learn(self):
        print('is learning')
    def eat(self):
        print('is eatting')

查找

stu1 = Student('张铁牛',22,'男')
print(stu1.Name)
print(stu1.Age)
print(stu1.Sex)

# 运行结果为:
张铁牛
22
男

stu1 = Student('张铁牛',22,'男')
stu1.Name = '李铁蛋'
print(stu1.Name)

# 运行结果为:
李铁蛋

删除

stu1 = Student('张铁牛',22,'男')
del stu1.Name
print(stu1.__dict__)   # 查看对象的名称空间

# 运行结果如下:
{'Age': 22, 'Sex': '男'}

增加

stu1 = Student('张铁牛',22,'男')
stu1.class_name = 'python开发'
print(stu1.__dict__)

# 运行结果如下:
{'Name': '张铁牛', 'Age': 22, 'Sex': '男', 'class_name': 'python开发'}

补给表达:

  • 站的角度差异,定义出的类是全然分裂的
  • 切切实实中的类并不完全等于程序中的类,比如现实中的集团类,在程序中有时需求拆分成都部队门类、业务类
  • 偶然为了编制程序须求,程序中也或然会定义出现实中不存在的类,举例计策类,现实中并不设有,但是在先后中却是二个很宽泛的事

天性查找与绑定方法

类有三种个性:数据属性和函数属性

1、类的数额属性是装有目的共享的

class Student:
    school = 'zhcpt'
    def __init__(self,name,age,sex):
        self.Name = name  # 就相当于往类的名称空间添加一个名字,是stu1的名称空间
        self.Age = age
        self.Sex = sex
    def learn(self):
        print('is learning')
    def eat(self):
        print('is eatting')

stu1 = Student('张全蛋',18,'男')  # 都有着相同的数据属性,school = 'zhcpt'
stu2 = Student('王小丽',16,'女')
stu3 = Student('李黑',23,'男')

她俩七个目的都定制了私家的特征:

print(stu1.__dict__)
print(stu2.__dict__)
print(stu3.__dict__)

# 运行结果如下:
{'Name': '张全蛋', 'Age': 18, 'Sex': '男'}
{'Name': '王小丽', 'Age': 16, 'Sex': '女'}
{'Name': '李黑', 'Age': 23, 'Sex': '男'}

走访类中的数据属性:是具备目标共有的

print(Student.school,id(Student.school))
print(stu1.school,id(stu1.school))
print(stu2.school,id(stu2.school))
print(stu3.school,id(stu3.school))

# 运行结果如下:
zhcpt 2347297903872
zhcpt 2347297903872
zhcpt 2347297903872
zhcpt 2347297903872

2、类的函数属性是绑定给目的使用的,称为对象的绑定方法

class Student:
    school = 'zhcpt'
    def __init__(self,name,age,sex):
        self.Name = name  # 就相当于往类的名称空间添加一个名字,是stu1的名称空间
        self.Age = age
        self.Sex = sex
    def learn(self):
        print('%s  is learning',self.Name)
    def eat(self):
        print('%s  is eatting',self.Name)

stu1 = Student('张全蛋',18,'男')  # 都有着相同的数据属性,school = 'zhcpt'
stu2 = Student('王小丽',16,'女')
stu3 = Student('李黑',23,'男')

做客类中的函数属性:是绑定给目的使用的,绑定到分裂的对象是见仁见智的绑定方法,对象调用绑定方法,就能把对象自己作为第一个参数字传送递给self

# 绑定方法,类的函数的内存地址,和对象的函数内存地址不一样
print(stu1.learn)  # <bound method Student.learn of <__main__.Student object at 0x0000027BFF0680B8>>

# 对象访问类中的函数属性,则将本身作为第一个参数传递给self
print(stu1.learn())

# 运行结果
张全蛋  is learning

绑定方法的情致就是调用的都以同样种效率,不过大家实施的都以个别区别的点子

stu1.learn()
stu2.learn()
stu3.learn()

# 运行结果如下:
张全蛋  is learning
王小丽  is learning
李黑  is learning

类中定义的函数属性,未有任何处理的话,不是给类用的,实际上是绑定给目标使用的,哪个人来调用正是什么人在采用这一个成效

类即类型

python中齐声都以目的,且python三中类与类型是二个概念,类型就是类

# 类型就是类
In [1]: print(list)

<class 'list'>

# 实例化3个对象
In [2]: l1 = list()

In [3]: l2 = list()

In [4]: l3 = list()

# 每个对象的绑定方法,都具有着相同的功能,但是内存地址不同
In [5]: print(l1.append)
<built-in method append of list object at 0x7ff344053e88>

In [6]: print(l2.append)
<built-in method append of list object at 0x7ff344035fc8>

In [7]: print(l3.append)
<built-in method append of list object at 0x7ff34431c5c8>

# 操作绑定方法l1.append(3),就是往l1里添加3,绝不会把3添加到l2或l3中
In [8]: l1.append(3)

In [9]: l1
Out[9]: [3]

In [10]: l2
Out[10]: []

In [11]: l3
Out[11]: []

# 调用类list.append(l3,111),实际上相当于:l3.append(111)
In [14]: list.append(l3,111)

In [15]: l3
Out[15]: [111]

从代码等级看面向对象

1、在尚未学习类这么些定义的时候,数据和意义是分手的

def exc1(host,port,db,charset):
    conn=connect(host,port,db,charset)
    conn.execute(sql)
    return xxx


def exc2(host,port,db,charset,proc_name)
    conn=connect(host,port,db,charset)
    conn.call_proc(sql)
    return xxx

#每次调用都需要重复传入一堆参数
exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;')
exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字')

二、大家就悟出了化解措施是,把那几个变量定义为全局变量

HOST=‘127.0.0.1’
PORT=3306
DB=‘db1’
CHARSET=‘utf8’

def exc1(host,port,db,charset):
    conn=connect(host,port,db,charset)
    conn.execute(sql)
    return xxx


def exc2(host,port,db,charset,proc_name)
    conn=connect(host,port,db,charset)
    conn.call_proc(sql)
    return xxx

exc1(HOST,PORT,DB,CHARSET,'select * from tb1;')
exc2(HOST,PORT,DB,CHARSET,'存储过程的名字')

三、不过二的化解格局也是不平时的,依照二的思绪,大家将会定义一大堆全局变量,那几个全局变量并从未做任何差异,即能够被全数功效利用,不过事实上唯有HOST,PORT,DB,CHALX570SET是给exc壹和exc贰那多少个作用用的。夹枪带棍:我们必须寻找1种能够将数据与操作数据的法门结合到3只的缓和措施,那正是我们说的类了

class MySQLHandler:
    def __init__(self,host,port,db,charset='utf8'):
        self.host=host
        self.port=port
        self.db=db
        self.charset=charset
        self.conn=connect(self.host,self.port,self.db,self.charset)
    def exc1(self,sql):
        return self.conn.execute(sql)

    def exc2(self,sql):
        return self.conn.call_proc(sql)


obj=MySQLHandler('127.0.0.1',3306,'db1')
obj.exc1('select * from tb1;')
obj.exc2('存储过程的名字')

计算运用类能够:将数据和专门操作该数额的意义整合到一块儿

可扩大性高

定义类并发生3个目的

class Chinese:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex


p1=Chinese('egon',18,'male')
p2=Chinese('alex',38,'female')
p3=Chinese('wpq',48,'female')

假使我们新添二个类属性,将会立时反应给全数目的,而目的却无需修改

class Chinese:
    country='China'
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def tell_info(self):
        info='''
        国籍:%s
        姓名:%s
        年龄:%s
        性别:%s
        ''' %(self.country,self.name,self.age,self.sex)
        print(info)


p1=Chinese('egon',18,'male')
p2=Chinese('alex',38,'female')
p3=Chinese('wpq',48,'female')

print(p1.country)
p1.tell_info()

小节练习

编写一个学生类,产生一堆学生对象
 要求:有一个计数器,统计总共实例化了多少对象
class Student:
    def __init__(self,name,sex,age):

        self.Name = name
        self.Sex = sex
        self.Age = age
        Student.count += 1

stu1 = Student('小明','男',14)
stu2 = Student('老王','男',38)
stu3 = Student('小丽','女',18)

此刻大家要想念二个标题,对象的天性是目的本人的,
所以….类的性质是豪门共有的

class Student:
    count = 0
    def __init__(self,name,sex,age):

        self.Name = name
        self.Sex = sex
        self.Age = age
        Student.count += 1

stu1 = Student('小明','男',14)
stu2 = Student('老王','男',38)
stu3 = Student('小丽','女',18)
print(Student.count)

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有