如何构建课程?

时间:2018-01-15 07:54:21

标签: python python-3.x

对于python 3中的以下代码,

class Spam(object):
  def __init__(self,name):
    self.name = name
  def bar(self):
    print('Am Spam.bar')

Spam的元类typeSpam的基类为object

我的理解是,

基类的目的是继承属性。 Metaclass用于构造给定的类定义,如下所示,

body= \
"""
def __init__(self, name):
  self.name = name
def bar(self):
  print('Am ', self.name)
"""
clsdict = type.__prepare__('type', 'Spam', (object,))
exec(body, globals(), clsdict)
Spam = type('Spam', (object,), clsdict)


s = Spam('xyz')
s.bar()

代码已经过测试here

使用给定的语法def __prepare__(metacls, name, bases)

__prepare__()是否需要传递'type'作为第一个参数?

1 个答案:

答案 0 :(得分:2)

type.__prepare__有点特殊,因为它忽略了传递给它的所有和任何参数并返回一个空的dict

>>> type.__prepare__()
{}

那就是说,你没有正确地呼叫__prepare__。它被调用:要创建的类的name,它的bases以及创建类的任何关键字参数。 __prepare__被称为metaclass.__prepare__(name, bases, **kwds)因此,

class MyClass(SomeBase, arg="value", metaclass=MyMeta):
    ...

__prepare__称为:

MyMeta.__prepare__("MyClass", (SomeBase,), arg="value")

但是,大多数用户定义的元类将其__prepare__定义为classmethod,这意味着隐式传递了元类。这意味着您的__prepare__定义可能如下所示:

@classmethod
def __prepare__(metaclass, name, bases, **kwargs):
    ...

但仍然以与以前相同的方式调用__prepare__。通过描述符的魔力,添加了metaclass参数。