封装、继承和多态
# 私有化 class Student: def __init__(self, name, age): self.name = name self.age = age def __str__(self): return '姓名:{}, 年龄:{}'.format(self.name, self.age) s1 = Student('张三', 18) print(s1) # 姓名:张三, 年龄:18 s1.age = -9 print(s1) # 姓名:张三, 年龄:-9
# 封装: 私有化属性, 定义公有set和get方法 # __属性: 将属性私有化,访问访问仅仅限于类中; 隐藏属性不被外界随意修改 class Student: def __init__(self, name, age): self.__name = name self.__age = age self.__score = 60 def setAge(self, age): if 0 < age < 120: self.__age = age else: print('年龄不准确') def getAge(self): return self.__age def __str__(self): return '姓名:{}, 年龄:{}'.format(self.__name, self.__age) s2 = Student('张三', 18) print(s2) # 姓名:张三, 年龄:18 s2.age = -9 print(s2) # 姓名:张三, 年龄:18 s2.setAge(-9) print(s2) # 年龄不准确 \n 姓名:张三, 年龄:18
print(dir(Student)) ''' ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'getAge', 'setAge'] ''' print(dir(s2)) ''' ['_Student__age', '_Student__name', '_Student__score', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'getAge', 'setAge'] ''' print(__name__) # __main__ #print(s2.__name) # AttributeError: 'Student' object has no attribute '__name' print(s2._Student__name) # 张三 print(s2.__dir__()) ''' ['_Student__name', '_Student__age', '_Student__score', '__module__', '__init__', 'setAge', 'getAge', '__str__', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__'] '''
私有化处理: 装饰器
# 装饰器 class Student: def __init__(self, name, age): self.name = name self.__age = age # def setAge(self, age): # if 0 < age < 120: # self.__age = age # else: # print('年龄不准确') # # def getAge(self): # return self.__age @property # 先有getXXX def age(self): return self.__age @age.setter # 再有setXXX def age(self, age): if 0 < age < 120: self.__age = age else: print('年龄不准确') def __str__(self): return '姓名:{}, 年龄:{}'.format(self.name, self.__age) s3 = Student('悟空',500) s3.name = '孙悟空' print(s3.name) # 孙悟空 s3.age = 130 # 年龄不准确 print(s3.age) # 500 print(s3.__dir__()) ''' ['name', '_Student__age', '__module__', '__init__', 'age', '__str__', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__'] '''
class Person: def __init__(self, name, age): print('**** Person的init初始化') self.__name = name self.__age = age def setName(self, name): self.__name = name def getName(self): return self.__name def setAge(self, age): self.__age = age def getAge(self): return self.__age def eat(self): print(self.__name + '正在吃饭...') def run(self): print(self.__name + '正在跑步...') class Student(Person): pass class Teacher(Person): pass s1 = Student('小花',14) s1.run() # 小花正在跑步... t1 = Teacher('王老师',45) t1.run() # 王老师正在跑步...
class Student(Person): def __init__(self, name, age, course): print('---> student的init') super().__init__(name, age) self.course = course def study(self, course): print('{}正在学习{}课程'.format(self.getName(), course)) def eat(self, food): super().eat() print(self.getName() + '正在吃饭..., 喜欢吃:' + food) class Employee(Person): def __init__(self, name, age, salary, manager): super().__init__(name, age) self.salary = salary self.manager = manager s2 = Student('Tom', 27, '三年五班') s2.run() s2.study('数学') ''' ---> student的init **** Person的init初始化 Tom正在跑步... Tom正在学习数学课程 '''
1. 如果类中不定义__init__, 调用父类 super class 的 __init__ 2. 如果类继承父类时也需要自定义自己的__init__, 需要在当前类的__init__调用父类的__init__ 3. 调用父类__init__: super().__init__(参数) super(类名,对象).__init__(参数) 4. 如果父类有eat()方法,子类也定义了eat()方法,默认搜索原则:先找当前类,再找父类 5. s2.eat() 重写(覆盖/override): 父类提供的方法不能满足子类的需求,子类中定义一个同名方法 s2.eat('西瓜') # Tom正在吃饭... # Tom正在吃饭..., 喜欢吃:西瓜
多重继承,inspect.getmro() 查看继承顺序
经典类: 从左向右, 深度优先
新式类: 广度优先
class Base: def test(self): print('--Base--test--') class A(Base): def test(self): print('--A--test--') class B(Base): def test(self): print('--B--test--') class C(Base): def test(self): print('--C--test--') class D(A, B, C): pass class E(B, C, A): pass c = C() c.test() # --C--test-- d = D() d.test() # --A--test-- e = E() e.test() # --B--test-- import inspect print(inspect.getmro(D)) ''' (<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Base'>, <class 'object'>) ''' print(inspect.getmro(E)) ''' (<class '__main__.E'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class '__main__.Base'>, <class 'object'>) '''
class A: def __init__(self): print('A') class B: def __init__(self): print('B') class C(A): def __init__(self): print('C') super(C, self).__init__() class D(A): def __init__(self): print('D') super(D, self).__init__() class E(C, B): def __init__(self): print('E') super(E, self).__init__() class F(C, D, B): def __init__(self): print('F') super(F, self).__init__() class G(D, B): def __init__(self): print('G') super(G, self).__init__() if __name__ == '__main__': import inspect g = G() print(inspect.getmro(G)) f = F() print(inspect.getmro(F)) e = E() print(inspect.getmro(E)) ''' G D A (<class '__main__.G'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>) F C D A (<class '__main__.F'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>) E C A (<class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>) '''
class Pet: role = '宠物' def __init__(self, nickname, age): self.nickname = nickname self.age = age def show(self): print('昵称:{}, 年龄:{}'.format(self.nickname, self.age)) class Cat(Pet): role = '猫' def catch_mouse(self): print('抓老鼠...') class Dog(Pet): role = '狗' def watch_house(self): print('看家...') class Tigger: role = '老虎' def eat(self): print('老虎吃人...') class Person: def __init__(self, name): self.name = name # pet既可以接收cat,也可以是dog, trigger def feed_pet(self, pet): print('{}喜欢养宠物:{}'.format(self.name, pet.role)) # 对pet参数进行判断,是不是类的对象,或者该类子类的对象 def feed_pet2(self, pet): if isinstance(pet, Pet): print('{}喜欢养宠物:{}, 昵称:{}'.format(self.name, pet.role, pet.nickname)) else: print('不是宠物,不能养...') cat = Cat('花花', 2) dog = Dog('旺财', 1) person = Person('管家') person.feed_pet(cat) # 管家喜欢养宠物:猫 tigger = Tigger() person1 = Person('阿拉伯人') person1.feed_pet(tigger) # 阿拉伯人喜欢养宠物:老虎 person2 = Person('俄罗斯人') person2.feed_pet2(tigger) # 不是宠物,不能养... person2.feed_pet2(dog) # 俄罗斯人喜欢养宠物:狗, 昵称:旺财
# 单例模式 class Student: def study(self, course): print('{}正在学习{}课程'.format(self.name, course)) s = Student() s1 = Student() s2 = Student() print(s) # <__main__.Student object at 0x000000C59D6931F0> print(s1) # <__main__.Student object at 0x000000C59D68F370> print(s2) # <__main__.Student object at 0x000000C59D68F3A0>
class Singleton: __instance = None # 私有化 def __new__(cls): # 重写__new__ print('----> __new__') if cls.__instance is None: cls.__instance = object.__new__(cls) return cls.__instance else: return cls.__instance def show(self, n): print('------->show', Singleton.__instance, n) singleton = Singleton() # ----> __new__ print(singleton) # <__main__.Singleton object at 0x000000835F74F220> singleton2 = Singleton() # ----> __new__ print(singleton2) # <__main__.Singleton object at 0x000000835F74F220> singleton3 = Singleton() # ----> __new__ print(singleton3) # <__main__.Singleton object at 0x000000835F74F220> singleton.show(5) # ------->show <__main__.Singleton object at 0x00000085247DF1F0> 5 singleton2.show(7) # ------->show <__main__.Singleton object at 0x00000085247DF1F0> 7