# 疑问:深浅拷贝是什么意思? ''' 类与对象的关系:对象都是由类产生的,上帝造人,上帝首先有一个造人的模板,这个模板既人的类,然后上帝根据类的定义来生产一个个的人 什么叫实例化:由类生产对象的过程叫实例化,类实例化的结果就是一个对象,或者叫做一个实例(实例=对象) ''' '''类相关知识''' # 声明类 # class 类名: # '类的文档字符串' # 类体 class Chinese: '''这是一个中国人的类''' pass print(Chinese) # <class '__main__.Chinese'> p1 = Chinese() # 实例化到底干了什么?实例化的过程,类加上括号就是实例化,会返回一个结果,相当于函数的return print(p1) # <__main__.Chinese object at 0x00000225BE6C79D0> # 经典类和新式类 # 大前提: # 1、只有在python2中才分新式类和经典类,python3中统一都是新式类 # 2、新式类和经典类声明的最大不同在于,所有新式类必须继承至少一个父类 # 3、所有类不管是否显示声明父类,都有一个默认继承object父类(讲继承时会讲,先记住) # 在python2中的区分 # 经典类: # class 类名: # pass # 新式类 # class 类名(父类): # pass # 在python3中,上述两种定义方式全都是新式类 ''' 属性:类是用来描述一类事物,类的对象指的是这一类事物中的一个个体;是事物就要有属性,属性分为 1:数据属性:就是变量 2:函数属性:就是函数,在面向对象里通常称为方法 注意:类和对象均用点来访问自己的属性 ''' # 类的属性:峰式理论---数据属性即变量,类的定义与函数又极其类似,其实可以用函数的作用域来理解类的属性调用 class Chinese_1: '''类的描述''' dang = 'gongchandang' def sui_di_tu_tan(): print('随地吐痰') def cha_dui(self): print('插到了前面') print(Chinese_1.dang) # 取到数据属性值 Chinese_1.sui_di_tu_tan() # 取到函数属性并运行 Chinese_1.cha_dui('随便传') # 取到函数属性并运行 # 查看类属性 print(dir(Chinese_1)) # 查看类的属性,是一个列表 print(Chinese_1.__dict__) # 查看类的属性字典,key为属性名,value为属性值 print(Chinese_1.__dict__['dang']) # 通过类的属性字典来取数据属性 Chinese_1.__dict__['sui_di_tu_tan']() # 通过类的属性字典来取函数属性 Chinese_1.__dict__['cha_dui']('也是随便传') # 通过类的属性字典来取函数属性 # 特殊属性 print(Chinese_1.__name__) # 类的名字Chinese_1 print(Chinese_1.__doc__) # 类的文档描述'类的描述' print(Chinese_1.__base__) # 类的第一个父类,也可以说是祖先'object' print(Chinese_1.__bases__) # 类的所有父类构成的元组 print(Chinese_1.__dict__) # 类的属性字典 print(Chinese_1.__module__) # 类定义所在的模块 '''对象相关知识''' class Chinese_2: '''类的描述''' dang = 'gongchandang' # 初始化过程__init__,只要类一运行就会自动加载__init__函数,self为实例本身,通过封装后可得到实例属性字典 def __init__(self, name, age, gender): self.mingzi = name self.nianji = age self.xingbie = gender def sui_di_tu_tan(): print('随地吐痰') def cha_dui(self): print(self) print('%s插到了队伍前面' % self.mingzi) index = 2 # p1 = Chinese_2() # 会报错,自动执行__init__方法,而这个方法需要参数,这些参数应该写在类名后面的括号里,然后由类传给__init__函数,也就说,传给类的参数就是传给__init__的参数 p1 = Chinese_2('alex', 29, 'man') # __init__(self, name, age, gender),p1其实相当于传给了self,也就是说self就是实例本身 print(p1) # <__main__.Chinese_2 object at 0x00000210E1347A00> print(p1.__dict__) # {'mingzi': 'alex', 'nianji': 29, 'xingbie': 'man'} print(p1.__dict__['mingzi']) # alex print(p1.mingzi) # alex # 实例有自己的数据属性,那么实例能否调用类的属性呢?调用属性用.其实也就是在自己的属性字典里去调用,p1调用的时候先在__init__函数里去找,找不到然后在类的属性字典中去找 print(p1.dang) print(p1.index) Chinese_2.sui_di_tu_tan() Chinese_2.cha_dui(p1) # 类调用函数属性时,不会自动传入参数,所以需要加上实例本身这个参数 # p1.sui_di_tu_tan() # 会报错,因为当实例调用类的函数属性时,会自动把实例当作参数传给类的方法,而该方法不需要传参数 p1.cha_dui() # 通过打印self会发现,其实结果和p1的打印结果是一样的,而且也运行了类的该方法!print(self) ------ <__main__.Chinese_2 object at 0x000001EF0D6C7A00>