Python 元类和插槽?

Python 元类和插槽?,python,Python,因此,我正在阅读一些关于Python中元类的内容,以及如何使用type()的三个参数alterego动态创建类。但是,第三个参数通常是初始化要创建的类的\uuu dict\uu变量的dict 如果我想基于使用\uuuuu slots\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?type()是否仍以某种方式与重写\uuuuuuuuuuuuuu()一起使用 仅供参

因此,我正在阅读一些关于Python中元类的内容,以及如何使用
type()
的三个参数alterego动态创建类。但是,第三个参数通常是初始化要创建的类的
\uuu dict\uu
变量的
dict

如果我想基于使用
\uuuuu slots\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?
type()
是否仍以某种方式与重写
\uuuuuuuuuuuuuu()
一起使用

仅供参考,我知道在创建大量类时,如何正确使用
\uuuuu slots\uuuu
,以节省内存,而不是滥用它来强制执行某种类型的安全性


设置
\uuuuuuu元类并使用
\uuuuu dict\uuuuuuuu
的普通(新型)类示例:

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

在上面的
中,将调用
type.\uuuuuu new\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。但是,如果我想修改
Meta
以包含
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu slots\uuuuuuuuuuuu
,那么我就没有字典可以传递给
type()
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu


编辑:一个快速但未经测试的猜测是将要放入
\uuuuuuuuuuuuuuuuuuuuuuuu
变量的值记录下来,并将其传递给
类型。\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。然后将一个
\uuuu init\uuuuuuuuuuuuuu()
添加到
Meta
,该Meta将填充来自dict的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>变量。尽管我不确定dict将如何到达
\uuuuuuuuuuuuuuuuuuuu,因为
\uuuuuuuuuuuuuuuuuuuuu
的声明会阻止创建
\uuuuuuuuuuuuuuuuuuuuuuuuu
,除非
中定义了
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

在元类示例中,dctn<代码>替换实例字典。如果创建两个示例:

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']
然后:


无法创建具有非空_____;属性的类型。您可以做的是在新类的dict中插入一个_uuslots _uuu属性,如下所示:

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 
现在,Foo具有时隙属性:

foo = Foo() 
foo.y = 1
投掷

 AttributeError: 'Foo' object has no attribute 'y'
更多关于元类中定义的插槽的信息。 如果
type
的子类定义了非空的
\uuuuuuuuuuuuuuuuuuuuu
,Python会抛出
TypeError


好的,我还在这里学习Python的诀窍,并开始学习Python的咒语“一切都是对象”(类似于UNIX的“一切都是文件”)。不可能在元类中定义
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
并将其传播到从元类创建的类中吗?或者这是基类变得更有用的地方?或者,我想结合这两个概念吗?好问题。当然,只需添加到
dctn
,就可以在元类中定义
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。然而,从基类生成子类通常是更好的方法。一般来说,如果你不确定你是否需要一个元类,那么你就不需要了。这就是为什么我要更多地学习元类,这样我才能确定我是否真的需要它们。请注意,我来自.NET的背景,在那里我必须处理泛型、接口和单一继承,并且从未接受过OOP的正式培训(只有一些关于旧C的课程)。试图理解Python的独特差异有时被证明是非常有趣的。就像一个人找到了一种方法,把一个孢子转化成一个投石机,在晚餐时把布鲁塞尔芽放在桌子上。这看起来很有趣。我会在几分钟后试试。我从来没有试过这个,但我认为这从技术上回答了这个问题。总有一天我会弄明白的。刚刚登录到SO in ages;这个答案最终奏效了。谢谢
 AttributeError: 'Foo' object has no attribute 'y'
In [1]:

class Meta(type):
    __slots__ = ('x')

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-38-1b16edef8eca> in <module>()
----> 1 class Meta(type):
      2     __slots__ = ('x')

TypeError: nonempty __slots__ not supported for subtype of 'type'
In [2]:

class Meta(type):
    __slots__ = ()

class Foo(metaclass=Meta):
    pass

type(Foo)

Out [2]:

__main__.Meta

In [3]:

Foo.y = 42
Foo.y

Out [3]:

42

In [4]:

Foo.__dict__

Out [4]:

mappingproxy({'y': 42, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__doc__': None, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__module__': '__main__'})

In [5]:

foo = Meta('foo', (), {})
type(foo).__slots__

Out [5]:

()

In [6]:

foo.x = 42
foo.x

Out [6]:

42

In [7]:

foo.__dict__

Out [7]:

mappingproxy({'__dict__': <attribute '__dict__' of 'foo' objects>, 'x': 42, '__module__': '__main__', '__doc__': None, '__weakref__': <attribute '__weakref__' of 'foo' objects>})

In [8]:

# Testing on non-metaclasses. Just in case.
class Bar:
    __slots__ = ()

b = Bar()
b.__dict__

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-54-843730c66f3f> in <module>()
      3 
      4 b = Bar()
----> 5 b.__dict__

AttributeError: 'Bar' object has no attribute '__dict__'