类属性
- 实例属性
- 不同实例不关联
- 私有属性
__
开头。__var
- 不能在类外访问
- 类属性
类名.变量名
- 所有实例共有
class test:
name = 'test' # 类属性
__sex = 'male' # 类私有属性
def __init__(self, id, phone=1008666):
self.id = id # 实例属性
self.__phone = phone # 实例私有属性
def get_sex():
return test.__sex
def get_phone(self):
return self.__phone
- 通常通过
_
开头来命名一些介于普通属性与私有属性之间的属性。
类方法总结
实例方法
class test:
def func(self, value, args):
# do something
构造方法 __init__()
class test(classA):
def __init__(self, args):
# 构造父类/父类初始化。
super.__init__()
self.id = args[0]
# ...
私有方法
def __func()
class test:
def __func(self, args):
# do something
析构方法 __del__()
- 使用
del()
删除对象时,调用此方法
class test:
def __del__(self):
# do something
print("Del class: test")
静态方法、类方法
- 静态方法
@staticmethod
修饰符。无隐含调用参数。- 不依赖对象状态
- 类方法
@classmethod
修饰符。必须有默认参数cls
- 用途1:构造实例
- 用途2:调用静态方法
cls.func()
- 两类方法调用都不需要实例化类
class test:
name = 'test'
def __init__(self, id):
self.id = id
@classmethod
def get_name(cls):
return cls.name
# 通过类方法构造实例
@classmethod
def from_Person(cls, person):
reutrn cls(person.id)
@staticmethod
def get_class_name():
return test.name
print(test.get_name)
pritn(test.get_class_name)
@property
- 设置为只读属性
- 需要返回或者生成一些东西
- 注意调用的时候
class Test:
@property
def get_hello(self):
return 'hello world'
t = Test()
print(t.get_hello)
class Test:
@classmethod
@property
def get_id(cls):
reutrn 12138
print(Test.get_id)
抽象方法
- 类似
Java
接口 - 继承后必须重写
doit
方法,否则报错
class Interface(object):
def doit(self):
raise NotImplementedError
class Dodo(Interface):
def doit(self, value):
return value-1/10
专有方法
方法 | 说明 |
---|---|
__init__ | 构造方法 |
__del__ | 析构方法 |
__repr__ | 打印,转换 |
__setitem__ | 按照索引赋值 |
__getitem__ | 按照索引获取值 |
__len__ | 获得长度 |
__cmp__ | 比较运算 |
__call__ | 函数调用 |
__add__ | 加运算 |
__sub__ | 减运算 |
__mul__ | 乘运算 |
__div__ | 除运算 |
__mod__ | 求余运算 |
__pow__ | 乘方 |
继承
- 子类继承父类的属性与方法
- 不能相互访问私有属性
- 可以多重继承
- 可以重写父类方法
class Person:
def __init__(self, name):
self.name = name
class Student(Person):
def __init__(self, name, id):
super.__init__(name)
# Person.__init__(name)
self.id = id
多重继承。
class Person:
def __init__(self, name):
self.name = name
class Men:
def __init__(self, wife):
self.wife = wife
class Me(Person, Men):
def __init__(self, name, wife, profile):
# Person.__init__(name)
# Men.__init__(wife)
print(Me.__mro__)
super().__init__(name) # Person.__init__()
super(Person,self).__init__(wife) # Men.__init__()
self.profile = profile
Liangzai = Me('Fry', 'None', None)
super
只是单个继承的话,可以理解为:super用来调用父类
,不存在什么问题。
但是,多重继承呢?
- 没有参数的情况下,可以只 super().init() 完成所有父类在子类的初始化,或者调用父类属性、方法
- 父类都有初始化参数的情况呢?该如何初始化父类?如上代码
先大概了解__mro__
- [ Method Resolution Order ]: 方法解析顺序
- 总之,
__mro__
的目的就是按照一定顺序,保证父类函数只调用一次。
察看Me
类的__mro__
属性
# print(Me.__mro__) #
(<class '__main__.Me'>, <class '__main__.Person'>, <class '__main__.Men'>, <class 'object'>)
__mro__
是一个元组- 类
Me
的__mro__
顺序是
Me -> Person -> Men -> object
。
- 如在类
Me
中 - 调用
super()
函数时传入的第一个参数是Me
(super(Me,self)
), - 那么
super()
函数就会在__mro__
里从Me
的上一级开始查找, - 它的上一级是
Person
- 那么
super(Me, self).__init__()
就调用Person
的__init__()
函数。
类似的:
super(Person, self).__init__()
调用的就是Men.__init__()
super(Me,self) <==> super() |