【问题标题】:What's relationship between dict and attrs in python?python中dict和attrs有什么关系?
【发布时间】:2018-02-26 02:15:59
【问题描述】:

我是python的初学者。我正在学习元类,但我不太了解字典如何存储方法和属性?

class ModelMetaclass(type):
    def __new__(cls, name, bases, attrs):
        if name=='Model':
            return type.__new__(cls, name, bases, attrs)
        print('Found model: %s' % name)
        mappings = dict()
        for k, v in attrs.items():
            if isinstance(v, Field):
                print('Found mapping: %s ==> %s' % (k, v))
                mappings[k] = v
        for k in mappings.keys():
            attrs.pop(k)
        attrs['__mappings__'] = mappings
        attrs['__table__'] = name 
        return type.__new__(cls, name, bases, attrs)

我假设 attrs 不仅可以存储变量,还可以存储方法。如果这样做,这本字典中的键和值是什么,attrs?

【问题讨论】:

  • 方法只是可调用的属性。对象属性通常存储在字典中,名为__dict__(也是一个属性,通过称为“槽”的机制)。
  • 如果您是初学者,可以暂时忽略元类。
  • 顺便说一下,将“attributes”缩写为“attrs”会造成混淆,因为有一个流行的 Python 库,名为 attrs

标签: python dictionary orm metaclass


【解决方案1】:

类的所有属性确实存储在字典中。请注意,方法也只是属性;他们恰好是可调用的。 Python 在很多地方都使用字典;例如,模块的全局命名空间也是字典。 object.__getattribute__ hook 的工作通常是将属性访问转换为属性字典中的键查找。

类语句的主体像函数一样执行,然后将生成的本地命名空间(调用locals() 生成的字典)交给元类以生成类对象。这就是 attrs 在您的示例代码中所绑定的内容。

class statement reference documentation

然后类的套件在新的执行框架中执行(参见[命名和绑定](然后类的套件在新的执行框架中执行(参见命名和绑定),使用新创建的本地命名空间和原始全局命名空间。(通常,套件主要包含函数定义。)当类的套件完成执行时,其执行帧被丢弃但其本地命名空间被保存。然后使用继承列表创建一个类对象基类和为属性字典保存的本地命名空间

我的大胆强调。

您可以在Metaclasses section of the datamodel documentation中找到更多详细信息;引用Creating the class object section:

通过执行类主体填充类命名空间后,通过调用metaclass(name, bases, namespace, **kwds)创建类对象

命名空间字典然后通过type.__new__()附加到新创建的类对象。

datamodel documentation 也涵盖了这一点,在 自定义类 部分下:

一个类有一个由字典对象实现的命名空间。类属性引用被翻译成这个字典中的查找,例如,C.x 被翻译成 C.__dict__["x"](尽管有许多钩子允许其他定位属性的方法)。

您可能还想阅读descriptors;方法是通过将类命名空间中的函数绑定到您在其上查找方法名称的实例来创建的。

【讨论】:

    猜你喜欢
    • 2015-04-26
    • 2012-05-16
    • 2012-06-21
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    相关资源
    最近更新 更多