SimPy BoundClass
_get_ 函数
一个类只要实现了 _get_ , _set_ , _delete_ 中的任意方法,我们就可以叫它描述器。如果只是定义了 _get_ 我们叫非资料描述器,如果 _set_, _delete_ 任意一个或者同时出现,我们叫资料描述器
首先明确一点,又有这个方法的类,应该(也可以说是必须)产生一个实例,并且这个实例是另外一个类的类属性(注意一定是类属性,通过self 的方式产生就不属于_get_ 范畴了)
也就是说又有这个方法的类,那么它的实例应该属于另外一个类/对象的一个属性。
代码实例
class TestDes:
def __get__(self, instance, owner):
print(instance, owner)
return "TestDes: __get__"
class TestMain:
des = TestDes()
# t = TestDes()
# 由于采用的是类访问,所以instance == None
TestMain.des
#由于采用的是实例访问,所以instance != None
t = TestMain()
t.des
测试结果
None <class ‘__main__.TestMain‘>
<__main__.TestMain object at 0x0000022D98914D30> <class ‘__main__.TestMain‘>
MehthodType 将类绑定到另一个实例上
class A():
def __init__(self, cls, name, age):
printf("name {}".format(name))
printf("age {}".format(age))
def hello(self):
print("hello")
class B():
def __init__(self):
self.h = types.MethodType(A, self)
开始测试
b = B() # 实例化b
a = b.h("xiaoMing","22") # A类的 init 第一个参数是 b这个对象
a.hello()
simpy core BoundClass 解读
class BoundClass(Generic[T]):
"""Allows classes to behave like methods.
The ``__get__()`` descriptor is basically identical to
``function.__get__()`` and binds the first argument of the ``cls`` to the
descriptor instance.
"""
def __init__(self, cls: Type[T]):
self.cls = cls
def __get__(
self,
instance: Optional[‘BoundClass‘],
owner: Optional[Type[‘BoundClass‘]] = None,
) -> Union[Type[T], MethodType]:
if instance is None:
return self.cls
return MethodType(self.cls, instance)
@staticmethod
def bind_early(instance: object) -> None:
"""Bind all :class:`BoundClass` attributes of the *instance‘s* class
to the instance itself to increase performance."""
for name, obj in instance.__class__.__dict__.items():
if type(obj) is BoundClass:
bound_class = getattr(instance, name)
setattr(instance, name, bound_class)
BoundClass 中通过MethodType 将类绑定到目标实例上。用户可以像使用属性一样调用类的实例。bind_early 可以将类属性添加到实例属性。
模拟一下 simpy BoundClass用法
import types
class A():
def __init__(self,cls,msg):
print(cls)
print(‘hello {}‘.format(msg))
class BoundClass():
def __init__(self, cls) -> None:
self.cls = cls # 要绑定的类
def __get__(self, instance, target):
# if instance is None:
# return self.cls
return types.MethodType(self.cls, target)
class B():
a = BoundClass(A)
# 轻松实现将 A 类绑定到 B 类中
B.a(‘wang‘)