Python的类和对象
1. 类和对象的定义
类用class关键字声明,类中的变量成为属性,函数成为方法,定义方法的时候,需要带上self参数。
例: class Person: # 默认继承Object父类,也可以继承Str,Number等父类 name = 'dog' age = 12 def fav(self): print('喜欢跑步。') person = Person() # 实例化类 person.name # dog person.fav() # 喜欢跑步
2. 类的继承和重写
类的继承,类B继承类A,继承父类的所有属性和方法 class A: x = 22 def name(self): print('我是A') class B(A): pass b = B() b.x # 22 b.name() # 我是A 类的多继承,一个类可以继承多个父类,如果父类中存在相同的方法或属性,则从左往右就近继承 class D: x = 333 y = 33 def name(self): print('我是D') class E(A,D): pass e = E() e.x # 22 e.y # 33 e.name() # 我是A 类的重写,类C继承类A,如果类C中存在和父类A相同的属性和方法名,则会重写父类的属性和方法的内容 class C(A): x = 222 def name(self): print('我是C') c = C(): c.x # 222 c.name # 我是C
3. 类的组合
类的组合,即将类作为值赋给另一个类中的属性 class Dog: def say(self): print('汪汪汪') class Cat: def say(self): print('喵喵喵') class Animal: dog = Dog() cat = Cat() def say(self): self.dog.say() self.cat.say() Animal().say() # 汪汪汪 喵喵喵
4. self的作用
slef的作用 class Self: x = 22 def get_self(self): return self mySelf = Self() # 他们的结果都是一样的,说明这个self指的是对象的本身 print(mySelf.get_self()) # <__main__.self object at 0x000002CB88A9CA08> print(mySelf) # <__main__.self object at 0x000002CB88A9CA08> 类实例化对象后方法是共享的,属性是私有的 mySelf.y = 33 print(mySelf.y) # 33,mySelf对象的私有属性y mySelf1 = Self() mySelf1.x # 22 x是共有属性,是实例化类的 mySelf1.y # AttributeError: 'self' object has no attribute 'y' mySelf1.z = 44 print(mySelf1.z) # 44,z是mySelf对象的私有属性 查看对象的内部私有属性 mySelf.__dict__ # {'y': 33} mySelf1.__dict__ # {'z': 44}
5. 类的私有变量
1.以__下划线命名,表示这是私有变量,外部无法正常去访问2.但是,他并不是一个真正的私有变量,他还是可以被外部访问到,只是被偷偷修改了名称,我们可以通过_类名+变量名来访问并操作值,并不建议
3._单个下划线开头的变量:代表仅供类内部使用的变量,约定俗成
例: class private: def __init__(self, x): self.x = x def set_x(self, x): self.__x = x def get_x(self): print(self.__x) myPrivate = private(100) print(myPrivate.__x) # 无法访问对象的内部私有属性值 通过内省,类内部的__x被改名为_private__x myPrivate.__dict__ # {'_privateVariable__x': 100} print(myPrivate._private__x) # 100 通过内部方法去修改值 myPrivate.set_x(200) 通过内部的方法去访问 myPrivate.get_x() # 200 也可以直接通过_类名+私有属性名的方式直接修改值 myPrivate._private__x = 300 myPrivate.get_x() # 300 不能通过动态添加对象属性的方法来增加类的属性 1. 直接通过添加变量的方式 myPrivate.y = 666 2. 通过字典的属性添加对象的属性__dict__[key] = value myPrivate.__dict__['z'] = 888 查看属性,发现属性的命名为发声改变,说明命名重写只发生在类内部产生的时候 print(myPrivate.__dict__) # {'_privateVariable__x': 300, 'y': 666, 'z': 888} 进一步验证,将类实例化另一个对象,并没有发现y和z的属性 myPrivate1 = private(1) print(myPrivate1.__dict__) # {'_privateVariable__x': 1} __slots__方法,限制对象可动态添加的属性,避免内存泄漏浪费 class Slots: __slots__ = ['x', 'y'] def __init__(self, x): self.x = x slots = Slots(100) print(slots.__dict__) # 报错,使用了__slots__方法就不存在__dict__方法了 print(slots.__slots__) # ['x', 'y'] 通过__slots__获取 可以添加__slots__中定义的属性名称,不可以随意添加 slots.y = 200 # 添加y属性 slots.z = 300 # 报错,因为__slots__不包含z属性 slots的继承 class S(Slots): pass s = S(666) print(s.x) # 666 继承了父类的属性 s.z = 777 print(s.z) # 777 可以添加自己的属性 print(s.__dict__) # {'z': 777} print(s.__slots__) # ['x', 'y']
6. 多肽
多肽:用一个函数调用类里面的方法,但是不确定调用的是哪个对象,首先类中要有函数中的方法
class A:
def XX(self):
print('我是AXX')
def YY(self):
print('我是AYY')
class B:
def XX(self):
print('我是BXX')
def YY(self):
print('我是BYY')
class C:
def XX(self):
print('我是CXX')
def YY(self):
print('我是CYY')
声明函数来调用不同的类
def showTime(x):
x.XX()
x.YY()
多肽调用
showTime(A())
showTime(B())
showTime(C())
7. min-in混入
# 继承 class Animal: def __init__(self, name, age): self.name = name self.age = age def say(self): print(f'我叫{self.name},今年{self.age}岁。') class Love(Animal): # 继承Animal类 def fav(self): print('我喜欢吃西瓜!') # 实例化,都继承了类的方法和属性 c = Love('小米', 100) print(c.__dict__) # {'name': '小米', 'age': 100} c.say() # 我叫小米,今年100岁。 c.fav() # 我喜欢吃西瓜! # 混入mixn-in # 在定义一个混入类 class mixin: def fly(self): print('我还喜欢飞翔') class myMix(Animal, mixin): def fav(self): print('我喜欢贵的东西!') d = myMix('TT', 27) print(d.say()) # 我叫TT,今年27岁。 print(d.fly()) # 我还喜欢飞翔 print(d.fav()) # 我喜欢贵的东西! # 混入经典案例 class Displayer: # 第四步:调用display方法,打印出内容 def display(self, message): print('222') print(message) class LoggerMixin: # 第八步:开始执行log方法 def log(self, message, filename='logfile.txt'): with open(filename, 'a') as f: f.write(message) # 第二步:调用display1方法 def display1(self, message): print('111') # 第三步:super()其实指向的是mySubClass类,因为它当中才继承了display方法,指向display方法 super().display(message) # 第六步:执行完毕display方法后,self指向subclass,所以mySubClasslog方法指向执行mySubClass类中的mySubClasslog方法 print('333') self.mySubClasslog(message) print('444') class mySubClass(LoggerMixin, Displayer): # 第七步:执行mySubClasslog方法 def mySubClasslog(self, message): # 在mySubClasslog方法中的super()就是实例subclass,所以log方法是继承LoggerMixin类的 super().log(message, filename='subclass.txt') print('555') subclass = mySubClass() # 第一步:首先调用mySubClass类中继承LoggerMixin类的方法display1 subclass.display1('this is mixin') # [<class '__main__.mySubClass'>, <class '__main__.LoggerMixin'>, <class '__main__.Displayer'>, <class 'object'>] print(mySubClass.mro())
浙公网安备 33010602011771号