一、三大编程范式:
面向过程:
面向函数:
面向对象:
二、程序的进化论:
1.编程最开始就是无组织无结构,从简单控制流中按步写指令
2.从上述的指令中提取重复的代码块或逻辑,组织到一起(比方说,你定义了一个函数),便实现了代码重用,且代码由无结构走向了结构化,创建程序的过程变得更具逻辑性
3.我们定义函数都是独立于函数外定义变量,然后作为参数传递给函数,这意味着:数据与动作是分离的
4.如果我们把数据和动作内嵌到一个结构(函数或类)里面,那么我们就有了一个‘对象系统’(对象就是数据与函数整合到一起的产物)。
三、面向对象初见面:
3.1
#你是谁?【名字、属性、特征、。。】你在干什么【动作】?千年的哲学问题!
两者组合起来:实现了两者的交互:对象正在做什么事情!
#狗的属性特征 dog1={\'name\':\'苑昊\',\'gender\':\'母\',\'type\':\'腊肠\'} dog2={\'name\':\'alex\', \'gender\':\'母\',\'type\':\'津巴\'} person={\'name\':\'武sir\', \'gender\':\'母\',\'type\':\'人\'} #狗的动作 def jiao(dog): print(\'一条狗[%s],汪汪汪\'%dog[\'name\'] ) def chi_shi(dog): print(\'一条狗[%s]正在吃屎\' %dog[\'type\']) jiao(dog1) chi_shi(dog1) chi_shi(dog2) jiao(person)
3.2、实现狗只能执行狗的动作,人执行狗的动作。 解决方法:绑定一块
解决方式:在对象里面加入属性的字段,之后在调用过程中,进行if判断。显得太low!
比较好的办法:
def dog(): # 狗的动作 def jiao(dog): print(\'一条狗[%s],汪汪汪\' % dog[\'name\']) def chi_shi(dog): print(\'一条狗[%s]正在吃屎\' % dog[\'type\']) # 狗的属性特征+属性 dog1 = {\'name\': \'苑昊\', \'gender\': \'母\', \'type\': \'腊肠\', \'jiao\': jiao, \'chi_shi\':chi_shi } return dog1 d1=dog() #拿到一个字典,里面有函数的内存地址 print(d1) d1[\'jiao\'](d1) >>>
{\'jiao\': <function dog.<locals>.jiao at 0x10207c9d8>, \'type\': \'腊肠\', \'gender\': \'母\', \'name\': \'苑昊\', \'chi_shi\': <function dog.<locals>.chi_shi at 0x10207ca60>} 一条狗[苑昊],汪汪汪
实现了:
字典dog1就是一个明确的对象:包含了狗的属性特征和动作(函数),内嵌动作的明确函数。有属性,有动作,就形成额一条完整的狗。
3.3、新的问题:狗的对象里面只有一条狗,被写死了。解决办法:作为参数传入。一个字典代表一一条狗的完整信息,批量生产字典
def dog(name,gender,type): # 狗的动作 def jiao(dog): print(\'一条狗[%s],汪汪汪\' % dog[\'name\']) def chi_shi(dog): print(\'一条狗[%s]正在吃屎\' % dog[\'type\']) # 狗的属性特征+属性 dog1 = {\'name\': name, \'gender\': gender, \'type\': type, \'jiao\': jiao, \'chi_shi\':chi_shi } return dog1 d1=dog(\'袁浩\',\'母\',\'京巴\') #拿到一个字典,里面有函数的内存地址:包含函数 d2=dog(\'alex\',\'母\',\'京巴\') #一个字典就是一条丰满的对象。每执行一次就生产一条狗。 print(d1) print(d2) d1[\'jiao\'](d1) d2[\'chi_shi\'](d2) >>> {\'name\': \'袁浩\', \'type\': \'京巴\', \'gender\': \'母\', \'chi_shi\': <function dog.<locals>.chi_shi at 0x10217cae8>, \'jiao\': <function dog.<locals>.jiao at 0x10217ca60>} {\'name\': \'alex\', \'type\': \'京巴\', \'gender\': \'母\', \'chi_shi\': <function dog.<locals>.chi_shi at 0x10217cbf8>, \'jiao\': <function dog.<locals>.jiao at 0x10217cb70>} 一条狗[袁浩],汪汪汪 一条狗[京巴]正在吃屎
3.4、定义初始化函数:init()完成初始化对象:一条狗函数最终一条活色生香的狗!————————————→ 明确的对象:一个独立的,完整的个体!是一个类具体的存在!
通过初始化函数把属性和正在进行的动作扎何在一块。
def dog(name,gender,type): # 狗的动作 def jiao(dog): print(\'一条狗[%s],汪汪汪\' % dog[\'name\']) def chi_shi(dog): print(\'一条狗[%s]正在吃屎\' % dog[\'type\']) # 狗的属性特征+属性:初始化一条完整的狗! def init(name,gender,type): dog1 = {\'name\': name, \'gender\': gender, \'type\': type, \'jiao\': jiao, \'chi_shi\':chi_shi } return dog1 return init(name,gender,type) d1=dog(\'袁浩\',\'母\',\'京巴\') #拿到一个字典,里面有函数的内存地址:包含函数 d2=dog(\'alex\',\'母\',\'京巴\') #一个字典就是一条丰满的对象。每执行一次就生产一条狗。 print(d1) print(d2) d1[\'jiao\'](d1) d2[\'chi_shi\'](d2) >>> {\'chi_shi\': <function dog.<locals>.chi_shi at 0x10333db70>, \'jiao\': <function dog.<locals>.jiao at 0x10333d9d8>, \'name\': \'袁浩\', \'type\': \'京巴\', \'gender\': \'母\'} {\'chi_shi\': <function dog.<locals>.chi_shi at 0x10333dae8>, \'jiao\': <function dog.<locals>.jiao at 0x10333da60>, \'name\': \'alex\', \'type\': \'京巴\', \'gender\': \'母\'} 一条狗[袁浩],汪汪汪
二、顺序调整
def school(name,hangye,type,): def init(name, hangye, type, ):#初始化函数:该对象的属性特征和动作函数的集合,下面是所有动作函数的明细 dic_q = { \'name\': name, \'hangye\': hangye, \'类型\': type, \'考试\': kaoshi, \'招生\': zhaoshen } return dic_q def kaoshi(school2): print(\'一所%s企业,名字是:%s, 正在进行一场考试\' %(school2[\'类型\'],school2[\'name\'])) def zhaoshen(school2): print(\'一所%s企业,名字是:%s, 正在进行招生\' % (school2[\'类型\'], school2[\'name\'])) return init(name,hangye,type,) school1=school(\'老男孩\',\'教育培训\',\'民营\',) print(school1) school1[\'招生\'](school1) school1[\'考试\'](school1) >>>> {\'hangye\': \'教育培训\', \'类型\': \'民营\', \'考试\': <function school.<locals>.kaoshi at 0x10333eae8>, \'招生\': <function school.<locals>.zhaoshen at 0x10333e9d8>, \'name\': \'老男孩\'} 一所民营企业,名字是:老男孩, 正在进行招生 一所民营企业,名字是:老男孩, 正在进行一场考试
3.5、类
对象:描述性特征+动作的结合。 针对类的一个明确的具体对象
类:一个种类,具有相同子对象的集合,来分区于其他的种类,共同特征+动作的集合。抽象的概念,抽象共同的特征,共同的动作!
3.6、面向对象设计和面向对象编程
1⃣️、面向对象设计:上面的用def函数的方法实现面向对象的过程就是
2⃣️、面向对象编程(object-oriented programming):用定义类+实例/对象的方式去实现面向对象的设计。用class独特的语法实现面向对象设计。
小结:
一门面向对象的语言不一定会强制你写 OO 方面的程序。例如 C++可以被认为“更好 的 C”;而 Java,则要求万物皆类,此外还规定,一个源文件对应一个类定义。
然而,在 Python 中, 类和 OOP 都不是日常编程所必需的。尽管它从一开始设计就是面向对象的,并且结构上支持 OOP,但 Python 没有限定或要求你在你的应用中写 OO 的代码
用面向对象语言写程序,和一个程序的设计是面向对象的,两者是八杆子打不着的两码事。
纯C写的linux kernel事实上比c++/java之类语言搞出来的大多数项目更加面向对象——只是绝大部分人都自以为自己到处瞎写class的面条代码才是面向对象的正统、而死脑筋的linus搞的泛文件抽象不过是过程式思维搞出来的老古董。
五 类和对象
1.什么叫类:类是一种数据结构,就好比一个模型,该模型用来表述一类事物(事物即数据和动作的结合体),用它来生产真实的物体(实例)。
2.什么叫对象:睁开眼,你看到的一切的事物都是一个个的对象,你可以把对象理解为一个具体的事物(事物即数据和动作的结合体)
(铅笔是对象,人是对象,房子是对象,狗是对象,alex是对象,配齐是对象,元昊是对象)
3.类与对象的关系:对象都是由类产生的,上帝造人,上帝首先有一个造人的模板,这个模板即人的类,然后上帝根据类的定义来生产一个个的人
4.什么叫实例化:由类生产对象的过程叫实例化,类实例化的结果就是一个对象,或者叫做一个实例(实例=对象)
5.1、类的相关知识
5.1.1 初识类
在python中声明函数与声明类很相似
声明函数
1 def functionName(args): 2 \'函数文档字符串\' 3 函数体
声明类
\'\'\' class 类名: \'类的文档字符串\' 类体 \'\'\' #我们创建一个类 class Data: pass #用类Data实例化出一个对象d1 d1=Data()
经典类与新式类
大前提: 1.只有在python2中才分新式类和经典类,python3中统一都是新式类 2.新式类和经典类声明的最大不同在于,所有新式类必须继承至少一个父类 3.所有类甭管是否显式声明父类,都有一个默认继承object父类(讲继承时会讲,先记住) 在python2中的区分 经典类: class 类名: pass 经典类: class 类名(父类): pass 在python3中,上述两种定义方式全都是新式类
5.1.2 属性
类是用来描述一类事物,类的对象指的是这一类事物中的一个个体
是事物就要有属性,属性分为
1:数据属性:就是变量
2:函数属性:就是函数,在面向对象里通常称为方法
注意:类和对象均用点来访问自己的属性
#类和对象的属性 \'\'\' 1、数据属性 2、函数属性 \'\'\' class Chinese: \'这是一个中国人的类\' dang= \'***\' #数据属性 def suiditutan(): print(\'朝着墙上就是一口痰\') def chadui(self): print(\'查到了前面\') print(Chinese.dang) #调用数据属性 Chinese.suiditutan() #调用函数属性 Chinese.chadui(\'yuanhao\') print(dir(Chinese))#查看该类下面的方法(列表类型,存放该类下所有属性名字,除了系统内置,还包含了:[\'chadui\', \'dang\', \'suiditutan\'])自定义 print(Chinese.__dict__) #查看类的属性字典:(返回字典:如:{\'suiditutan\': <function Chinese.suiditutan at 0x10217c9d8>}) print(Chinese.__dict__[\'dang\']) print(Chinese.__dict__[\'suiditutan\'])#内存地址 print(Chinese.__dict__[\'suiditutan\']()) # 总结:[类名.方法]本质上是通过(类.__dict__sh)调用该方法 # p1=Chinese() #实例化的过程,相当于函数ruturn返回的结果 # print(p1)
*** 朝着墙上就是一口痰 查到了前面 [\'__class__\', \'__delattr__\', \'__dict__\', \'__dir__\', \'__doc__\', \'__eq__\', \'__format__\', \'__ge__\', \'__getattribute__\', \'__gt__\', \'__hash__\', \'__init__\', \'__le__\', \'__lt__\', \'__module__\', \'__ne__\', \'__new__\', \'__reduce__\', \'__reduce_ex__\', \'__repr__\', \'__setattr__\', \'__sizeof__\', \'__str__\', \'__subclasshook__\', \'__weakref__\', \'chadui\', \'dang\', \'suiditutan\'] {\'suiditutan\': <function Chinese.suiditutan at 0x10217c9d8>, \'__doc__\': \'这是一个中国人的类\', \'__module__\': \'__main__\', \'__weakref__\': <attribute \'__weakref__\' of \'Chinese\' objects>, \'dang\': \'***\', \'__dict__\': <attribute \'__dict__\' of \'Chinese\' objects>, \'chadui\': <function Chinese.chadui at 0x10217ca60>} *** <function Chinese.suiditutan at 0x10217c9d8> 朝着墙上就是一口痰 None
总结:
峰式理论:数据属性即变量,类的定义与函数又极其类似,其实可以用函数的作用域来理解类的属性调用
类的数据属性
#定义一个中文人的类,然后在类中定义一个类的属性,政府是***,这样,只要是中文人他们的党永远都是*** #类属性又称为静态变量,或者是静态数据。这些数据是与它们所属的类对象绑定的,不依赖于任何类实例。 #如果你是一位Java或C++程序员,这种类型的数据相当于在一个变量声明前加上static关键字。 class ChinesePeople: government=\'***\' print(ChinesePeople.government)
类的函数属性(又称为方法)
class ChinesePeople: government=\'***\' def sui_di_tu_tan(): print(\'90%的中国人都喜欢随地吐痰\') def cha_dui(self): print(\'一个中国人-->%s<--插到了前面\' %self) ChinesePeople.sui_di_tu_tan() person1_obj=\'alex\' ChinesePeople.cha_dui(person1_obj) #带参函数,所以调用时需要传入参数,将\'alex\'传给self
查看类属性
我们定义的类的属性到底存到哪里了?有两种方式查看
dir(类名):查出的是一个名字列表
类名.__dict__:查出的是一个字典,key为属性名,value为属性值
特殊的类属性
class ChinesePeople: \'我们都是中国人,我们骄傲的活着,我们不服任何事和物\' government=\'***\' def sui_di_tu_tan(): print(\'90%的中国人都喜欢随地吐痰\') def cha_dui(self): print(\'一个中国人-->%s<--插到了前面\' %self) print(ChinesePeople.__name__)# 类C的名字(字符串) print(ChinesePeople.__doc__)# 类C的文档字符串 print(ChinesePeople.__base__)# 类C的第一个父类(在讲继承时会讲) print(ChinesePeople.__bases__)# 类C的所有父类构成的元组(在讲继承时会讲) print(ChinesePeople.__dict__)# 类C的属性 print(ChinesePeople.__module__)# 类C定义所在的模块 print(ChinesePeople.__class__)# 实例C对应的类(仅新式类中)
5.2 对象相关知识
对象是由类实例化而来,类实例化的结果称为一个实例或者称作一个对象
5.2.1 实例化
class Chinese: \'这是一个中国人的类\' dang= \'***\' #数据属性 # def __init__(self,name,age,gender): #初始化函数,__init__系统内置,自动把函数的参数传入来。最外层无需参数 # dic={ # \'name\':name, # \'age\':age, # \'gender\':gender # } # return dic def __init__(self,name,age,gender): #初始化函数定制每一个对象的属性(数据,函数) self就是实例本身 print(\'初始化函数开始运行了\') #运行该类,就立即运行__init__函数 self.mingzi=name #p1.mingzi=name #运行类的时候会自动找到内置的__init__方法来运行:P1.mingzi=name self.nianji=age #p1.mingzi=name #有一个默认的self参数,之后是数据属性。{\'nianji\':age,\'xingbie\':age} self.xingbie=gender #p1.mingzi=name #定义数据属性;self.mingzi 赋予了一个mingzi的数据属性 print(\'我结束了\') #最后把P1封装成为一个字典 #最后自动由class自动帮忙return: self的数据属性。返回的是一个字典属性P1\'\'默认:return None def suiditutan(): print(\'朝着墙上就是一口痰\') def chadui(self): print(\'查到了前面\') # return init(name,age,gender) 无需return,自动运行 #实例化的过程,本质上调用init函数.self就是实例本身 p1=Chinese(\'袁浩\',\'18\',\'female\') #->>>__init__(self,name,age,gender)实例化过程中,P1会自动传给self #相当于:p1=Chinese.__init__(p1 ,name,age,gender) print(Chinese.__dict__) print(p1) print(p1.__dict__) #可以通过__dict__调用显示字典,解释见前面的过程 #p1=Chinese() #类的运行过程就是一个实例化。 >>> 初始化函数开始运行了 我结束了 {\'dang\': \'***\', \'__module__\': \'__main__\', \'__weakref__\': <attribute \'__weakref__\' of \'Chinese\' objects>, \'chadui\': <function Chinese.chadui at 0x10217cae8>, \'__dict__\': <attribute \'__dict__\' of \'Chinese\' objects>, \'__doc__\': \'这是一个中国人的类\', \'suiditutan\': <function Chinese.suiditutan at 0x10217ca60>, \'__init__\': <function Chinese.__init__ at 0x10217c9d8>} <__main__.Chinese object at 0x102180550> {\'xingbie\': \'female\', \'mingzi\': \'袁浩\', \'nianji\': \'18\'}
5.2.2 构造函数
数据属性:
class Chinese: \'这是一个中国人的类\' dang= \'
***
\' #数据属性 def __init__(self,name,age,gender): self.mingzi=name self.nianji=age self.xingbie=gender def suiditutan(): print(\'朝着墙上就是一口痰\') def chadui(self): print(\'查到了前面\') p1=Chinese(\'袁浩\',\'18\',\'female\') print(Chinese.__dict__) print(p1) print(p1.__dict__[\'mingzi\']) #可以通过__dict__调用显示字典,解释见前面的过程 print(p1.mingzi) #直接通过 . 来调用 #P1这个人里面包含自己的数据属性。
实例的数据属性的作用域
class Chinese: \'这是一个中国人的类\' dang= \'***\' #数据属性 def __init__(self,name,age,gender): self.mingzi=name self.nianji=age self.xingbie=gender def suiditutan(): print(\'朝着墙上就是一口痰\') def chadui(self): print(\'查到了前面\') p1=Chinese(\'袁浩\',\'18\',\'female\') #P1这个人里面包含自己的数据属性。 #由一个类产生的一个实例,那么这个实例应该具备这一类该有的数据属性和函数属性。可以通过.来获取数值 print(p1.__dict__) #里面是p1所有的数据集合 print(p1.mingzi)#到实例的属性字典里面去寻找数据 print(p1.dang)#??可以对于不在属性字典里面数据和函数也可以找到。可以用峰氏理论:作用域来解释! #现在自己位置寻找,找不到的话,在上一级寻找。P1产生的字典是由chinese类帮忙产生的!【p1=Chinese(\'袁浩\',\'18\',\'female\')】 #由Chinese类去触发运行__init__,所以P1的字典是由init产生的,所以作用域就在init函数里面。 #对于:p1.dang首先在init的作用域内找,没找打的情况下,去外一层找。直到找到类的最里一层。
上述的实例化过程,没有做任何事情,啥意思?
类是数据属性和函数属性的结合,描述的是一类事物
这类事物的一个具体表现就是一个实例/对象,比方说中国人是一个类,而你就是这个类的一个实例
你除了有中国人这个数据属性外,还应该有名字,年龄,性别等数据属性
如何为实例定制数据属性,可以使用类的一个内置方法__init__()该方法,在类()实例化是会自动执行
class ChinesePeople: \'我们都是中国人,我们骄傲的活着,我们不服任何事和物\' government=\'***\' def __init__(self,name,age,gender): #实例化的过程可以简单理解为执行该函数的过程,实例本身会当作参数传递给self(这是默认的步骤) self.name=name self.age=age self.gender=gender def sui_di_tu_tan(): print(\'90%的中国人都喜欢随地吐痰\') def cha_dui(self): print(\'一个中国人-->%s<--插到了前面\' %self) # person1=ChinesePeople() #会报错 #自动执行__init__方法,而这个方法需要参数, # 这些参数应该写在类名后面的括号里,然后由类传 #给__init__函数,也就说,传给类的参数就是传给__init__的参数 person1=ChinesePeople(\'alex\',1000,\'female\') person2=ChinesePeople(\'wupeiqi\',10000,\'female\') person3=ChinesePeople(\'yuanhao\',9000,\'female\') print(person1.__dict__)
注意:在说实例化的时候说过,执行类()会自动返回一值,这个值就是实例,而类()会自动执行__init__,所以一定不要在该函数内定义返回值,会冲突(不怕死可以自己测试)
5.2.3、实例的属性:
class Chinese: \'这是一个中国人的类\' dang= \'***\' #数据属性 def __init__(self,name,age,gender): self.mingzi=name self.nianji=age self.xingbie=gender def suiditutan(): print(\'朝着墙上就是一口痰\') def chadui(self): print(self.__dict__)#就是实例化的 print(\'%s查到了前面\'%self.mingzi) p1=Chinese(\'袁浩\',\'18\',\'female\') print(p1.__dict__) #只有实例的数据属性 谁来实例化,self就是谁! print(Chinese.__dict__) #数据属性和函数属性都有 Chinese.suiditutan() #在作用域范围内,可以调用该函数。类调用 Chinese.chadui(p1) #可以通过参数传递,进行赋值和调用name。完成通过,类的调用,显然太low!
#通过实例调用 #p1.suiditutan() #首先会在p1的实例字典里面去找该字典,无法找到情况下,去外层找。 # 报错!默认会把p1参数传入。相当于:p1.suiditutan(p1)。传给第一个位置参数 可是函数设置的时候,没有参数传入。所以报错! p1.chadui() #可以运行, #一、谁来实例化,self就是谁,如上述:print(self.__dict__)#就是实例化的打印结果: #{\'mingzi\': \'袁浩\', \'xingbie\': \'female\', \'nianji\': \'18\'} #二、 self做了一个统一。只要执行函数 #所以说实例只有数据属性。函数属性通过类查找
{\'xingbie\': \'female\', \'nianji\': \'18\', \'mingzi\': \'袁浩\'}
{\'dang\': \'***\', \'__weakref__\': <attribute \'__weakref__\' of \'Chinese\' objects>, \'__module__\': \'__main__\', \'__init__\': <function Chinese.__init__ at 0x10217c9d8>, \'suiditutan\': <function Chinese.suiditutan at 0x10217ca60>, \'__doc__\': \'这是一个中国人的类\', \'chadui\': <function Chinese.chadui at 0x10217cae8>, \'__dict__\': <attribute \'__dict__\' of \'Chinese\' objects>}
朝着墙上就是一口痰
{\'xingbie\': \'female\', \'nianji\': \'18\', \'mingzi\': \'袁浩\'}
袁浩查到了前面
{\'xingbie\': \'female\', \'nianji\': \'18\', \'mingzi\': \'袁浩\'}
袁浩查到了前面
峰式理论:
1.实例只有数据属性(实例的函数属性严格来说是类的函数属性)
2.del 实例/对象,只是回收了实例的数据属性,函数属性是属于类的,是不会回收。
实例化的过程实际就是执行__init__的过程,这个函数内部只是为实例本身即self设定了一堆数据(变量),所以实例只有数据属性
class ChinesePeople: \'我们都是中国人,我们骄傲的活着,我们不服任何事和物\' government=\'***\' def __init__(self,name,age,gender): self.name=name self.age=age self.gender=gender def sui_di_tu_tan(): print(\'90%的中国人都喜欢随地吐痰\') def cha_dui(self): print(\'一个中国人-->%s<--插到了前面\' %self) person1=ChinesePeople(\'alex\',1000,\'female\') print(person1.__dict__) #查看实例的属性,发现里面确实只有数据属性 print(person1.name,person1.age,person1.gender) #访问实例的数据属性
那么我们想访问实例的函数属性(其实是类的函数属性),如何实现
class ChinesePeople: \'我们都是中国人,我们骄傲的活着,我们不服任何事和物\' government=\'***\' def __init__(self,name,age,gender): self.name=name self.age=age self.gender=gender def sui_di_tu_tan(): print(\'90%的中国人都喜欢随地吐痰\') def cha_dui(self): print(\'一个中国人-->%s<--插到了前面\' %self) person1=ChinesePeople(\'alex\',1000,\'female\') print(person1.__dict__) #查看实例的属性,发现里面确实只有数据属性 print(ChinesePeople.__dict__)#函数属性只存在于类中 ChinesePeople.cha_dui(person1)#我们只能通过类去调用类的函数属性,然后把实例当做变量传递给self
一个小小的改进,就大不一样了
class ChinesePeople: \'我们都是中国人,我们骄傲的活着,我们不服任何事和物\' government=\'***\' def __init__(self,name,age,gender): self.name=name self.age=age self.gender=gender def sui_di_tu_tan(): print(\'90%的中国人都喜欢随地吐痰\') # def cha_dui(self): # print(\'一个中国人-->%s<--插到了前面\' %self) def cha_dui(self): print(\'一个中国人-->姓名:%s 年龄:%s 性别:%s<--插到了前面\' %(self.name,self.age,self.gender)) def eat_food(self,food): print(\'%s 正在吃 %s\' %(self.name,food)) person1=ChinesePeople(\'alex\',1000,\'female\') print(person1.__dict__) #查看实例的属性,发现里面确实只有数据属性 print(ChinesePeople.__dict__)#函数属性只存在于类中 ChinesePeople.cha_dui(person1)#我们只能通过类去调用类的函数属性,然后把实例当做变量传递给self ChinesePeople.eat_food(person1,\'韭菜馅饼\') person1.cha_dui()#其实就是ChinesePeople.cha_dui(person1) person1.eat_food(\'飞禽走兽\') #本质就是ChinesePeople.eat_food(person1,\'飞禽走兽\')

总结:
所以说实例只有数据属性。函数方法属性通过类去查找。
一、谁来实例化,self就是谁,如上述:print(self.__dict__)#就是实例化的打印结果:
#{\'mingzi\': \'袁浩\', \'xingbie\': \'female\', \'nianji\': \'18\'}
二、 self做了一个统一。只要执行函数
三、实例调用的函数方法,都是到类里面去查找的。
通过数据属性和函数属性的分离,→init的数据属性可以快速生产多个实例,每个实例到类里面去要方法。和每个实例都分别定义数据属性和函数属性要更加的高效,同时省内存!
四、方式类当中定义的方法,默认都有一个参数self,放在函数的第一个位置。通过对象调用的时候,会自动把自己传递给self.
5.2.4 查看实例属性
同样是dir和内置__dict__两种方式
5.2.5 特殊实例属性
__class__
__dict__
class ChinesePeople: \'我们都是中国人,我们骄傲的活着,我们不服任何事和物\' government=\'***\' def __init__(self,name,age,gender): self.name=name self.age=age self.gender=gender def sui_di_tu_tan(): print(\'90%的中国人都喜欢随地吐痰\') # def cha_dui(self): # print(\'一个中国人-->%s<--插到了前面\' %self) def cha_dui(self): print(\'一个中国人-->姓名:%s 年龄:%s 性别:%s<--插到了前面\' %(self.name,self.age,self.gender)) def eat_food(self,food): print(\'%s 正在吃 %s\' %(self.name,food)) person1=ChinesePeople(\'alex\',1000,\'female\') print(person1.__class__) print(ChinesePeople) person2=person1.__class__(\'xiaobai\',900,\'male\') print(person2.name,person2.age,person2.gender) 具体用法
警告:类和对象虽然调用__dict__返回的是一个字典结构,但是千万不要直接修改该字典,会导致你的oop不稳定
5.3 类属性与对象(实例)属性
#类属性又称为静态变量,或者是静态数据。这些数据是与它们所属的类对象绑定的,不依赖于任何类实例。 #如果你是一位Java或C++程序员,这种类型的数据相当于在一个变量声明前加上static关键字。 class ChinesePeople: country=\'China\' def __init__(self,name): self.name=name def play_ball(self,ball): print(\'%s 正在打 %s\' %(self.name)) def say_word(self,word): print(\'%s 说 %s\' %(self.name,word)) #查看类属性 print(ChinesePeople.country) #修改类属性 ChinesePeople.country=\'CHINA\' print(ChinesePeople.country) #删除类属性 del ChinesePeople.country #增加类属性 ChinesePeople.Country=\'China\' ChinesePeople.location=\'Asia\' print(ChinesePeople.__dict__) #类的数据属性增删改查与函数属性是一样的 ChinesePeople.say_word=say_word print(ChinesePeople.__dict__) alex_obj=ChinesePeople(\'alex\') ChinesePeople.say_word(alex_obj,\'我是一只来自北方的狼狗\') 类属性使用
class ChinesePeople: country=\'China\' def __init__(self,name): self.name=name def play_ball(self,ball): print(\'%s 正在打 %s\' %(self.name,ball)) p1=ChinesePeople(\'alex\') print(p1.__dict__) #查看实例属性 print(p1.name) # print(p1.age)#不存在于p1的属性字典中,会报错 print(p1.country)#country也不存在于p1的属性字典中,为何可以取到呢? #删除 # del p1.country #报错,因为p1的属性字典里根本就没有country属性 del p1.name print(p1.__dict__) #增加 p1.gender=\'man\' print(p1.__dict__) #修改 p1.gender=\'woman\' print(p1.__dict__) 实例属性的使用
1.其实你会发现,实例化就是 类名(),然后返回的结果是一个对象,加上括号是不是跟函数运行很像,函数运行完了有返回值,是不是很像,没错,就是一样的。
2.函数又作用域的概念,其实类也有作用域的概念,二者一样
3.你可以把class当做最外层的函数,是一个作用域
#定义一个类,只当一个作用域去用,类似于c语言中的结构体 class MyData: pass x=10 y=20 MyData.x=1 MyData.y=2 print(x,y) print(MyData.x,MyData.y) print(MyData.x+MyData.y)
4.实例化会自动触发init函数的运行,最后返回一个值即实例,我们要找的实例属性就存放在init函数的局部作用域里
5.类有类的属性字典,就是类的作用域,实例有实例的属性字典,即实例的作用域
6.综上,一个点代表一层作用域,obj.x先从自己的作用域找,自己找不到去外层的类的字典中找,都找不到,就会报错
7.在类中没有使用点的调用,代表调用全局变量啊,这还tm用说,对,你就是不知道
age=1000 class ChinesePeople: country=\'China\' age=10 def __init__(self,name): self.name=name print(\'初始化函数中调用age\',age) #不加点调用就跟类没关系了,找的就是全局的 print(\'初始化函数中调用self.age\',self.age) def play_ball(self,ball): print(\'%s 正在打 %s\' %(self.name,ball)) def say_word(self,word): print(\'%s 说 %s\' %(self.name,word)) p1=ChinesePeople(\'alex\') print(p1.age) #这属于在自己的作用域定义了一个age,类的age并不会变 p1.age=100000000 print(p1.age) print(ChinesePeople.age) #不是说实例无函数属性吗,他都是调用的类的,那么我们就为实例添加一个函数属性好了 p1.haha=say_word print(p1.__dict__) p1.haha(p1,\'英语\')#我擦嘞,怎么会这么玩 我就不信玩不懵你
age=10000000000 class ChinesePeople: country=\'China\' age=10 def __init__(self,name): self.name=name def play_ball(self,ball): print(\'%s 正在打 %s\' %(self.name,ball)) p1=ChinesePeople(\'alex\') p2=ChinesePeople(\'wupeiqi\') p3=ChinesePeople(\'yuanhao\') p1.age=1000 p2.age=10000 p3.age=9000 print(p1.age,p2.age,p3.age) print(\'全局变量\',age) print(\'类数据属性\',ChinesePeople.age) #开始玩你了 age=10000000000 class ChinesePeople: country=\'China\' age=10 l=[] def __init__(self,name): self.name=name def play_ball(self,ball): print(\'%s 正在打 %s\' %(self.name,ball)) p1=ChinesePeople(\'alex\') p2=ChinesePeople(\'wupeiqi\') p3=ChinesePeople(\'yuanhao\') p1.l.append(\'p1\') p2.l.append(\'p2\') p3.l.append(\'p3\') print(ChinesePeople.l) print(p1.l,p2.l,p3.l) 换个姿势搞你
峰式理论 :类的作用域即函数作用域