613 字
3 分钟
继承
__slots__
当我们创建了一个 class 后,可以动态的给这个实例绑定任何属性和方法
class Student(Object): pass
s = Student()s.name = 'FlyingWhite'
def set_age(self,age): self.age = age
from types import MethodTypes.set_age = MethodType(set_age,s)#给实例绑定一个方法,但是这个方法对其他的实例不起作用
为了给所有的实例都绑定.可以直接给 class 绑定方法
Student.set_age = set_age
这样后所有的实例都可以调用.
如果我们想限制实例的属性咋办?比如我们只想要 name
和 age
,这个时候我们可以用一个 __slot__
变量来限制他的属性
class Student: __slot__ = ('name','age')
使用@property
在绑定属性的时候,可以直接把属性暴露出去,虽然简单,但是这样就没办法检查参数了,导致可以随意修改,因此我们可以设置一个 get_score
class Student: def set_score(self,value:int): if isinstance(value,int): self._score = value else: raise ValueError("score must be an integer")
但是上面的方法还挺复杂的,我们可以使用装饰器来动态的加上功能,python 内置的 @property
就是用来干这个的
class Student: @property def name(self): return self._name
@name.setter def name(self, name): if not isinstance(name, str): raise TypeError("name must be a string") self._name = name
s = Student()s.name = 60#实际为s.name(60)s.name#s.name()
还可以定义只读属性,只定义 getter 方法,不定义 setter 方法就是一个只读属性:
class Student(object): @property def birth(self): return self._birth
@birth.setter def birth(self, value): self._birth = value
@property def age(self): return 2015 - self._birth
多重继承
class Animal: ...
class Runnalbe: def run(self): ...
class Mammal(Animal): ...
class Dog(Mammal,Runnable): ...
定制类
python 中有一些方法是特殊的,有特殊的作用
class Student: def __init__(self, name, age): self.name = name self.age = age
def __str__(self): return f"Name: {self.name}, Age: {self.age}"
def __iter__(self): return self
def __next__(self): self.age += 1 if self.age > 100: raise StopIteration # 迭代终止 return self def __call__(self): print("你好")#使用实例.()直接调用
元类 Metaclass
我们可以使用 type() 来查看一个类型或变量的类型,比如 Hello 是一个 class,那么他的类型就是 type
,而 hello 是 Hello 的实例,他的类型就是 class Hello
type()
函数既可以返回一个对象的类型,又可以创建出新的类型,比如,我们可以通过 type()
函数创建出 Hello
类,而无需通过 class Hello(object)...
的定义:
https://liaoxuefeng.com/books/python/oop-adv/meta-class/index.html
ABC 抽象基类
Class abc.ABC
这是一个使用 ABCMeta 作为元类的辅助类,使用这个类可以简单的从 ABC 派生方法创建抽象基类
from abc import ABC
class MyABC(ABC): @abstractmethod def __iter__(self): ...