继承
class A: def f1(self): print('A') class B(A): def Bar(self): print('B') self.f1() class C: def f1(self): print('C') class D(B,C): def f(self): print('D') obj = D() obj.Bar()
以上代码执行结果
B
A
先找自己,再找左边,左边找完再找右边。
执行父类的构造方法
class Animal: def __init__(self): print('构造方法') self.ty = '动物' class Cat(Animal): def __init__(self): print('cat构造方法') self.n = '猫' # 执行父类的构造方法
方法一 super(Cat,self).__init__()
方法二
# Animal.__init__(self) c_obj = Cat() print(c_obj.__dict__) print(c_obj.n) print(c_obj.ty)
以上代码运行结果:
cat构造方法 构造方法 {'n': '猫', 'ty': '动物'} 猫 动物
子类继承一个带构造方法__init__的父类,如果子类没有重写__init__,子类将会继承父类的__init__。
如果子类重写了__init__,子类将不会继承父类的__init__。
想要继承父类的__init__,必须在子类的__init__里执行父类的构造方法:super(Son,self).__init__()
实例:
当子类继承父类,且子类要重写构造方法时,最好做如下操作:
class Father(object): def __init__(self,*args,**kwargs): self.a = 'a' class Son(Father): def __init__(self,*args,**kwargs): super(Son, self).__init__(*args,**kwargs)
多态
多种形态
class Dog(object): def print_self(self): print("大家好,我是旺财") class Xiaotq(Dog): def print_self(self): print("hello everyone, i am Xiaotq") def introduce(temp): temp.print_self() dog1 = Dog() xiaotq = Xiaotq() introduce(dog1) introduce(xiaotq)
输出
大家好,我是旺财 hello everyone, i am Xiaotq
利用反射查看面向对象成员属性
实例一:
class Foo: def __init__(self, n): self.name = n def show(self): print('we') # 反射 # 反射:类,只能找类里的成员 # r = hasattr(Foo, 'show') # print(r) # 反射:对象,可以找对象里的成员和类里的成员 obj = Foo('zhou') r = hasattr(obj, 'name') print(r) r = hasattr(obj, 'show') print(r)
以上代码执行结果
True
True
实例二:
s1.py
class Foo: def __init__(self, n): self.name = n def show(self): print('we')
s2.py
# 导入模块 r = __import__('s1') # 从模块中找类 class_name = getattr(r,'Foo') # 根据类创建一个对象 obj = class_name('zhou') # 从对象中找name对应的值 n = getattr(obj,'name') print(n)
以上代码运行结果:
zhou
类属性、类方法、实例属性、实例方法、静态方法
class Game(object): #类属性 num = 0 def __init__(self): self.name = "xiaowang" #类方法 @classmethod def add_num(cls): cls.num = 100 #静态方法 @staticmethod def print_menu(): print("""测试菜单""") game = Game() Game.add_num()#通过类名调用类方法 game.add_num()#通过实例对象调用类方法 print(Game.num) print(game.num) Game.print_menu()#通过类名调用静态方法 game.print_menu()#通过实例对象调用静态方法
输出
100 100 测试菜单 测试菜单
面向对象三大特性:封装、继承、多态
快速判断,类执行,对象执行:
有self,对象调用
无self,类调用
成员修饰符,公有,私有(__)
私有,只能在当前类中调用
class Foo: xo = 'xo' __ox ='ox' def __init__(self): self.name = 'zhou' self.__n = 'zhou' def fetch(self): print(Foo.__ox) print(self.__n) obj = Foo() obj.fetch() # 强制访问私有普通字段 print(obj._Foo__n)
以上代码执行结果:
ox
zhou
zhou
类的特殊成员
__init__、__del__、__call__、__getitem__、__setitem__、__delitem__
class Foo: """ 注释 """ def __init__(self): print('init') self.name = 'zhou' def __call__(self, *args, **kwargs): print('call') return 1 def __getitem__(self, item): print(item) def __setitem__(self, key, value): print(key,value) def __delitem__(self, key): print(key) obj = Foo()
# 对象后面加(),执行__call__方法 print(obj()) # 调用__getitem__方法 obj['look'] obj[1:3] # 调用__setitem__方法 obj['panda'] = 'animal' obj[1:3] = [11,22,33] # 调用__delitem__方法 del obj['panda'] del obj[1:3] print(obj.__dict__) print(Foo.__dict__)
以上代码执行结果:
init call 1 look slice(1, 3, None) panda animal slice(1, 3, None) [11, 22, 33] panda slice(1, 3, None) {'name': 'zhou'} {'__module__': '__main__', '__doc__': '\n 注释\n ', '__setitem__': <function Foo.__setitem__ at 0x000001DB49969B70>, '__call__': <function Foo.__call__ at 0x000001DB49969A60>, '__init__': <function Foo.__init__ at 0x000001DB499699D8>, '__delitem__': <function Foo.__delitem__ at 0x000001DB49969BF8>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__getitem__': <function Foo.__getitem__ at 0x000001DB49969AE8>, '__dict__': <attribute '__dict__' of 'Foo' objects>}
__iter__方法
class Foo: def __iter__(self): yield 1 yield 2 yield 3 obj = Foo() # 如果执行for循环对象时,自动会执行对象的iter方法,iter是一个生成器 for i in obj: print(i)
__str__方法
class Foo: def __init__(self,name): self.name =name def __str__(self): return self.name obj = Foo('zhou') print(obj)
以上代码执行结果:
zhou
__all__方法
#指定模块可以导入的变量,函数或类,未指定的无法被导入 __all__ =["test", "Test"] def test(): print("-----test-----") class Test(object): pass