Discuss / Python / 请教老师同学们两个问题:

请教老师同学们两个问题:

Topic source

hi4gf

#1 Created at ... [Delete] [Delete and Lock User]

问题1:

往Model类添加class方法,就可以让所有子类调用class方法 往Model类添加实例方法,就可以让所有子类调用实例方法

为什么添加方法还要有这种区分?两者有什么区别? 最后不都是给实例调用,为何不全写成实例方法的形式呢? class方法不是应该写在metaclass里面吗?

class Model(dict, metaclass=ModelMetaclass):

    def __init__(self, **kw):
        super(Model, self).__init__(**kw)

问题2: Model对dict和 metaclass的继承关系是什么? 是不是Model被 metaclass里的类生产方法修改包装一遍,

这里我理解和修饰器的功能类似

然后,在Model实例生成的时候,就一路super上去找父类继承,并且带上metaclass里面的各种attrs??

逝去的9211

#2 Created at ... [Delete] [Delete and Lock User]

问题1:classmethod和实例method的区别在于类方法可以被类对象直接调用。注意看classmethod的第一个参数cls,当该类存在子类时,如果子类调用该方法,则cls传入的参数值是该子类对象。

没有说classmethod一定要在元类里面。

问题2: 这里涉及到python的类这个对象究竟事实怎么创建的。 简单来讲,python解释器在读到class定义语句时,使用type()函数来创建类对象。 而关键字参数metaclass,python解释器指示需要通过传入到参数metaclass的元类的new来创建类对象。 注意看metaclass里面的new返回值是调用的type的new.

hi4gf

#3 Created at ... [Delete] [Delete and Lock User]

谢谢您。对于第一个问题,我的理解是:

def __new__(cls, name, bases, attrs)

这里的bases就是Model的父类dict吧?

对于第二个问题,还想请问一下init里面的语句(super等)是在初始化实例的时候运行的吧? 那super寻找到Model的父类dict里面的init来进行初始化实例,那该实例如何继承到:

type.__new__(cls, name, bases, attrs)

这个类里面的特性的呢?

逝去的9211

#4 Created at ... [Delete] [Delete and Lock User]

第一个问题,new里面的bases参数应该是父类的list或tuple,而不是dict。 init是类对象的实例在初始化时调用的。

你的最后一个问题没明白意思。

python的解释器在遇到所有的class定义的时候,是调用type()函数来创建类对象的(不是类对象的实例)。本质是调用type.new函数来创建该类对象。 而type.new里面的参数cls是子类。这是调用父类的函数的区别。 Model类在创建时,使用metaclass里面的new创建,而metaclass里面的new函数对传入的attrs做了一系列操作。类似于decorator的作用。也就是说,我对类的定制。

hi4gf

#5 Created at ... [Delete] [Delete and Lock User]

在创建类对象Model时:new里面传入的父类bases就是(dict,) 在创建类对象User时:new里面传入的父类bases就是(Model,)

对吗?


  • 1

Reply