所以,我正在阅读Python中的元类,以及如何使用type()三参数alter-ego来动态创建类.但是,第三个参数通常是dict初始化要创建的类的__dict__变量.
如果我要动态地创建基于使用一元类类__slots__,而不是__dict__,我怎么可能做到这一点?是type()仍然以某种方式使用覆盖一起__new__()?
作为一个FYI,我知道正确的用途__slots__,在创建大量类时节省内存而不是滥用它来强制执行类型安全的形式.
设置__metaclass__和使用以下内容的普通(新式)类的示例__dict__:
class Meta(type):
def __new__(cls, name, bases, dctn):
# Do something unique ...
return type.__new__(cls, name, bases, dctn)
class Foo(object):
__metaclass__ = Meta
def __init__(self):
pass
Run Code Online (Sandbox Code Playgroud)
在上文中,type.__new__()被调用,第四个参数(它成为当实际使用的第三)创建了一个__dict__在Foo.但是,如果我想修改Meta包括__slots__,那我也没有字典传递到type()的__new__()函数(据我所知-我没有测试过任何这还没有,只是琢磨,并试图找到某种用途 - 情景).
编辑:快速但未经测试的猜测是将值放入__slots__变量并将其传递给变量type.__new__().然后添加一个__init__()to Meta来填充__slots__dict中的变量.虽然,我不确定该dict将如何达到__init__(),因为除非在...中定义了__slots__防止__dict__创建的声明__dict____slots__
jjm*_*jjm 23
您无法创建具有非空__slots__属性的类型.你可以做的是在新类的dict中插入__slots__属性,如下所示:
class Meta(type):
def __new__(cls, name, bases, dctn):
dctn['__slots__'] = ( 'x', )
return type.__new__(cls, name, bases, dctn)
class Foo(object):
__metaclass__ = Meta
def __init__(self):
pass
Run Code Online (Sandbox Code Playgroud)
现在Foo有一些插槽属性:
foo = Foo()
foo.y = 1
Run Code Online (Sandbox Code Playgroud)
投
AttributeError: 'Foo' object has no attribute 'y'
Run Code Online (Sandbox Code Playgroud)
dctn在您的元类示例中是类字典,而不是实例字典.__slots__替换实例字典.如果您创建两个示例:
class Meta(type):
def __new__(cls, name, bases, dctn):
return type.__new__(cls, name, bases, dctn)
class Foo1(object):
__metaclass__ = Meta
class Foo2(object):
__metaclass__ = Meta
__slots__ = ['a', 'b']
Run Code Online (Sandbox Code Playgroud)
然后:
>>> f1 = Foo1()
>>> f2 = Foo2()
>>> f1.__dict__ is Foo1.__dict__
False
>>> f2.__dict__
Traceback (most recent call last):
...
AttributeError: 'Foo2' object has no attribute '__dict__'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2839 次 |
| 最近记录: |