python 静态 封装 继承 mro 接口 super
1.静态属性 静态方法 类方法
#!/usr/bin/python env # encoding: utf-8 # 静态属性 静态方法 class Room: tag = 168 def __init__(self, owner, width, length): self.owner = owner self.width = width self.length = length # @propert是装饰器 total_area()函数属性可以用total_area调用 # 静态属性 可访问类的和实例属性 @property def total_area(self): return self.width * self.length # 类方法 能访问类的属性不能访问实例属性 和类绑定 不和实例绑定 @classmethod def test_tag(cls, x): print("from test_tag tag is %s ,x is %s" % (cls.tag, x)) # 静态方法 名义上归属类管理 不能访问类属性和实例属性 不和类 实例绑定 只是类的工具包 @staticmethod def action(a, b, c): print("%s %s %s" % (a, b, c)) r1 = Room('zhangsan', 100, 100) print(r1.total_area) Room.test_tag(1) r1.test_tag("12")
2.继承
含义:声明某个子类兼容于某个基类,定义一个接口类,子类继承接口类,并且实现接口中的定义的方法,又叫接口继承。
接口、口提取了一群类共同的函数,可以把接口当做一个函数的集合。然后让子类去实现接口中的函数。
这么做的意义在于归一化,什么叫归一化,就是只要是基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,从用法上来说都一样。
# 接口继承 父类规范子类 子类都要写父类的实现方法,不然实例化会报错
# 接口类只是规范 子类中没必要都要实现 但要定义
import abc class All_file(metaclass=abc.ABCMeta): @abc.abstractmethod def read(self): pass @abc.abstractmethod def write(self): pass class Mem(All_file): def read(self): print("mem read") class Disk(All_file): def read(self): print("disk read") def write(self): print("disk write") M = Mem() # Can't instantiate abstract class Mem with abstract methods write D = Disk() D.read() D.write()
经典类 新式类
1.只有在python2中才分新式类和经典类,python3中统一都是新式类 2.在python2中,没有显式的继承object类的类,以及该类的子类,都是经典类 3.在python2中,显式地声明继承object的类,以及该类的子类,都是新式类 3.在python3中,无论是否继承object,都默认继承object,即python3中所有类均为新式类 #关于新式类与经典类的区别,我们稍后讨论
# 继承顺序 MRO # 经典类深度优先 class A: # 新式类广度优先 class A(object):
# 注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表
class A(object): def test(self): print('from A') class B(A): def test(self): print('from B') class C(A): def test(self): print('from C') class D(B): def test(self): print('from D') class E(C): def test(self): print('from E') class F(D, E): # def test(self): # print('from F') pass f1 = F() f1.test() print(F.__mro__) # 只有新式才有这个属性可以查看线性列表,经典类没有这个属性 # 新式类继承顺序:F->D->B->E->C->A # 经典类继承顺序:F->D->B->A->E->C # python3中统一都是新式类 # python2中才分新式类与经典类
调用父类方法
a.即父类名.父类方法()
b.super()
# 类三大属性:继承 封装 多态 # 继承 当类之间具有很多相同功能,提取相同功能,定义为基类,用继承,当类之间具有很多不同功能,用组合 # 实践中 继承少用 因为它使得父类和子类强耦合性 最好定义为接口继承
class School:
def __init__(self, name, addr):
self.name = name
self.addr = addr
def test(self):
print("school")
class Course(School):
def __init__(self, name, addr, course, school, price):
# School.__init__(self, name, addr)
super().__init__(name, addr)
self.course = course
self.school = school
self.price = price
def info(self):
msg = "姓名:%s,课程:%s,学费:%s,地址:%s,学校名称:%s" % (self.name, self.course, self.price, self.addr, self.school)
return msg
def test(self):
print("->")
super().test()
print("-->")
c1 = Course("zhangsan", "上海", "python", "学校A", 1000)
print(c1.info())
c1.test()
print(c1.info()) # 姓名:zhangsan,课程:python,学费:1000,地址:上海,学校名称:学校A