# 面向对象 # 类:把一类事物的共有的属性和方法整合到一起就是类 # 对象:基于类而创建的一个具体的事物 # 类有两种属性:数据属性和函数属性 # 1. 类的数据属性是所有对象共享的(属性) # 2. 类的函数属性是绑定给对象用的(方法) class Person: # 类名一般首字母大写 country = '中国' # 数据属性,所有对象共享 def __init__(self, name, age, gender): # 初始化方法,实例化时会自己执行些方法 self.name = name # self指自己,谁实例化就是谁,后面产生一个实例p,这里就相当于 p.name = name self.age = age self.gender = gender def study(self): # 凡是类中定义的方法,第一个参数必须是self print('%s在学习' % self.name) # 函数属性 def eat(self, food): print('%s正在吃%s' %(self.name, food)) print(Person.__dict__) # 查看类的属性字典 print(Person.__name__) # 查看类的名字 print(Person.__base__) # 查看类的第一个父类 print(Person.__bases__) # 查看类的所有父类构成的元组 print(Person.__module__) # 查看类所在的模块 print(Person.__class__) # 查看类对应的类(仅新式类中) # 实例化(叫做对象或者叫做实例) p = Person('张三', 18, '男') # 相当于 __init__(p,'张三', 18, '男') p就对应self # 实例中只保存自己的数据属性,实例调用的方法都是从类中去找的 # 也就是说新创建的实例没有函数属性,可以自行给实例再添加它的函数属性 # 实例调用类中的方法 p.study() p.eat('面包') # 类属性的增删改查 # 查看类属性 print(Person.country) # 修改类属性 Person.country = '美国' # 增加类属性 Person.newclass = '新类属性的值' print(Person.newclass) # 删除类属性 del Person.newclass print(Person.__dict__) # 属性列表中已经没有newclass了 # 增加函数属性 def run(self): # 先定义一个函数,写法与类中的写法一致 print('%s正在跑步' %self.name) Person.run = run # 再将刚才定义的函数赋值到Person中的run属性 # 注意不要加括号,加括号相当于调用函数,不加括号就只是传递函数的内存地址 print(Person.__dict__) # 属性列表中已经有run这个函数属性了 # 实例属性的增删改查 # 查看实例的属性列表 print(p.__dict__) # 查看实列属性 print(p.name) print(p.age) print(p.gender) # 查看实例绑定的类的函数属性 print(p.eat) # 结果为<bound method Person.eat of <__main__.Person object at 0x009FC410>> # 增加实例的数据属性 p.height = '180cm' print(p.height) # 增加实例的函数属性 一般情况下不这样做 def test(): # 这里不需要加上self,因为self是对应类的函数属性的,而不是实例的函数属性 print('我是来自实例的函数属性') p.test = test p.test() # 修改实例的数据属性 p.height = '175cm' # 删除实例的数据(函数)属性 del p.height del Person # 删除类 # 注意,在类中定义的属性,需要通过.来查找(.查找只会在类中查找),如果未使用.则会寻找类外的全局变量 num = 10 class Getnum: num = 20 def __init__(self): print(self.num) # 这里获取的是类中的num 20 print(num) # 这里获取的是全局变量num 10 n = Getnum() del Getnum # 另一个例子 class OtherE: l = [1, 2] def __init__(self): pass o = OtherE() o.l.append(3) # 这里使用了append ,因为o里没有l这个列表,所以它操作的是类里的l o.l = [4, 5] # 这里相当于给o这个实例增加了数据属性l print(OtherE.l) # [1, 2, 3] print(o.l) # [4, 5] del OtherE # 静态属性 @property 将类中定义的函数属性,通过装饰器@property将其封闭成数据属性 # 可以访问类的所有属性,及实例的所有属性 # 封装以后所有的对该函数的操作,就像是操作数据属性 class Room: def __init__(self, length, width): self.length = length self.width = width @property def area(self): #求房间面积的函数属性 return self.length*self.width r = Room(20, 10) print(r.area) # 如未封装,我们需要使用r.area()来调用 del Room # 类方法 @classmethod 不实例化任何对象,直接可以通过类来调用其函数属性,跟实例没任何关系,只是类调用自己的方法 # 可以访问类的数据属性与类的函数属性 class Room: def __init__(self, length, width): self.length = length self.width = width @classmethod def area(cls): # 这里参数为cls,表示接收一个类,而不是调用该类的对象self print('这里是类方法') Room.area() del Room # 静态方法 @staticmethod 只是名义上归属类管理,不能使用类与实例的所有属性,是类的工具包 class Room: def __init__(self, length, width): self.length = length self.width = width @staticmethod def area(): print('这里是静态方法') Room.area() r = Room(200, 100) r.area() # python3.6.5可以这样调用 del Room # 类的组合 用于做类与类之间的关联(类与类之间无共同点),比如组合一个人 class Hand: pass class Foot: pass class Body: pass class Head: pass class Person: def __init__(self, id, name): self.id = id self.name = name self.Hand = Hand() self.Foot = Foot() self.Body = Body() self.Head = Head()