Python - 类型(名称,基数,字典)

时间:2014-03-24 12:22:54

标签: python python-3.x dictionary namespaces base

文档:

  

使用三个参数,返回一个新的类型对象。这实际上是类语句的动态形式。 name 字符串是类名,并成为__name__属性; bases 元组逐项列出基类并成为__bases__属性; dict 字典是包含类体定义的命名空间,并成为__dict__属性。

在学习Python时,我发现这种类型的使用是“类声明的动态形式”,这看起来非常有趣和有用,我希望能更好地理解它。有人可以清楚地解释__name____bases____dict__在班级中的作用,并举例说明type(name, bases, dict)自身的作用。

3 个答案:

答案 0 :(得分:9)

定义类时:

class Foo(Base1, Base2):
    bar = 'baz'

    def spam(self):
         return 'ham'

Python基本上是这样做的:

def spam(self):
    return 'ham'
body = {'bar': 'baz', 'spam': spam}

Foo = type('Foo', (Base1, Base2), body)

然后将Foo添加到命名空间中,定义了class语句。

class语句下的块被执行,好像它是一个没有参数的函数,并且生成的本地命名空间(字典)构成了类体;在这种情况下,会形成一个包含'bar''spam'键的字典。

您可以通过将名称字符串,基类元组和带字符串键的字典传递给type()函数来实现相同的结果。

一旦你开始探索元类(它们基本上是type()的子类 ,让你自定义类的创建方式),你会发现body 是一个普通的字典。 PEP 3115 - Metaclasses in Python 3将可能的值扩展为任何 dict(如),让您通过让增强的字典用于类体来实现各种有趣的类行为。例如,新的Python 3.4 enum module使用OrderedDict() instance来保留属性排序。

答案 1 :(得分:2)

__name__是一个包含该类名称的字符串 __bases__是当前类派生的类的元组 __dict__是类中定义的所有方法和字段的字典。

type(name, bases, dict)的用例是您希望在运行时动态生成类 想象一下,您想为数据库创建ORM,并且您希望自动生成表示数据库表的所有类。您知道这些类应该如何表现,但在检查数据库模式之前,您不知道它们的名称和字段。然后你可以使用这个函数来生成这些类。

答案 2 :(得分:1)

就像

一样
a = Foo()

创建Foo的实例并将其分配给a

Foo = type('Foo', (object,), {})

创建type的实例并将其分配给Foo。这不仅允许您动态创建类(类似于但不限于使用lambda来创建函数),但它允许您(正确地)将type视为函数,但作为一种类型本身。 type的实例是一个类对象。 type.__new__创建对象,type.__init__初始化它,type.__call__允许您将类用作可调用对象(这又是Foo()创建和初始化{{1}实例的方式}})。

了解Foo是您理解元类的方法。当您没有指定元类时,Python使用type来创建类,就像您编写的那样(在Python 2.x中)

type

就像你可以继承普通类一样,你可以继承class Foo(object): __metaclass__ = type 来创建你自己的元类!

type

如果运行上述内容,则会在执行class mymetaclass(type): def __new__(cls, name, bases, dict): print "Creating a subclass of {0} named {1}".format(name, bases) print "{0} will have the following attributes:".format(name) for key in dict: print " * {0}".format(key) # This class statement is (roughly) identical to: # # def foo_init(self, x): # self.y = x # # Foo = mymetaclass('Foo', (object,), { 'a': 3, '__init__': foo_init }) # (The class statement will also ensure that `__module__` and `__metaclass__` # are in the dict passed to mymetaclass.__new__.) class Foo(object): __metaclass__ = mymetaclass a = 3 def __init__(self, x): self.y = x 语句时看到生成的输出,因为执行class语句时会执行mymetaclass.__new__。 / p>