__slot__描述符如何在python中工作?
我知道__slots__
做什么,它应该用于什么。__slot__描述符如何在python中工作?
但是,我还没有找到一个全面的答案,如何使用__slots__
创建的member
描述符的下层机制的作品。
对象级别的值在哪里实际存储?
有没有办法改变这些值,而不直接属性访问描述符?
(例如:上课时C
有__dict__
你可以做C.__dict__['key']
代替C.key
)
通过创建类似的类级别的描述可以在一个“扩展” __slots__
对象定义的不变性?并进一步阐述这一点;可以使用元类构建一个不可变的对象,但是通过手动创建所述描述符来明确定义__slots__
?
回答:
__slot__
属性被分配在该对象的本机存储器的表示,和相关联的访问然后实际的类描述符使用本地C方法CPython的设置和检索归因于每个时隙中的Python对象的参考属性上类实例作为C结构。
描述符的插槽,在Python名为member_descriptor
呈现在这里定义:https://github.com/python/cpython/blob/master/Objects/descrobject.c
您不能执行或以任何方式提高从纯Python代码,这些描述符不使用ctypes的与本地代码进行交互。
有可能通过做类似
class A: __slots__ = "a"
member_descriptor = type(A.a)
去他们的类型,那么可以supose将有可能继承它,并写出推导__get__
和__set__
方法,可以做到chekings和这样的 - 但不幸的是,它不能作为基类。
但是,可以编写其他并行描述符,这些描述符可以调用本地描述符来实际更改代码。 通过使用元类,可以在创建类时重命名传入的__slots__
并将它们的访问包装在可执行额外检查的自定义描述符中 - 甚至可以从“dir”中隐藏。
所以,对一个天真的类型检查插槽变种元类,一个人可能
class TypedSlot: def __init__(self, name, type_):
self.name = name
self.type = type_
def __get__(self, instance, owner):
if not instance:
return self
return getattr(instance, "_" + self.name)
def __set__(self, instance, value):
if not isinstance(value, self.type):
raise TypeError
setattr(instance, "_" + self.name, value)
class M(type):
def __new__(metacls, name, bases, namespace):
new_slots = []
for key, type_ in namespace.get("__slots__", {}).items():
namespace[key] = TypedSlot(key, type_)
new_slots.append("_" + key)
namespace["__slots__"] = new_slots
return super().__new__(metacls, name, bases, namespace)
def __dir__(cls):
return [name for name in super().__dir__() if name not in cls.__slots__]
以上是 __slot__描述符如何在python中工作? 的全部内容, 来源链接: utcz.com/qa/265407.html