613 字
3 分钟
继承
2025-01-01

__slots__#

当我们创建了一个 class 后,可以动态的给这个实例绑定任何属性和方法

class Student(Object):
pass
s = Student()
s.name = 'FlyingWhite'
def set_age(self,age):
self.age = age
from types import MethodType
s.set_age = MethodType(set_age,s)#给实例绑定一个方法,但是这个方法对其他的实例不起作用

为了给所有的实例都绑定.可以直接给 class 绑定方法

Student.set_age = set_age

这样后所有的实例都可以调用.

如果我们想限制实例的属性咋办?比如我们只想要 nameage,这个时候我们可以用一个 __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):
...