类的继承、元类

A900616A 2013-07-06 04:40:43
有个问题 不明白 希望各位大神帮忙看看

class baseform(object):
pass

class FromMeta(type):
def __init__(cls, name, base, attr):
print 'FormMeta init'
type.__init__(cls, name, base, attr)

class Form(FromMeta('base', (baseform,), {"name":'jiangnan'})):
def __init__(self):
print 'Form init'

class loginForm(Form):
def __init__(self):
print 'loginForm init'

if __name__ == '__main__':

a = loginForm()


以上代码输出的结果是:
FormMeta init
FormMeta init
FormMeta init
loginForm init
[Finished in 0.4s]

看不懂为什么那里执行了三遍,不太明白执行过程, 谁能稍微详细的解释一下不? 回答满意的话100分全给你
...全文
670 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
A900616A 2013-08-16
  • 打赏
  • 举报
回复
引用 2 楼 maievshabu 的回复:
lz。类能继承实例吗?还有class fromMeta(type),type又是什么啊?这是3.0的写法吗?为什么我看书的时候都没看到这种写法?PS:新手!
看3楼的回复
A900616A 2013-08-16
  • 打赏
  • 举报
回复
引用 3 楼 adlay 的回复:
首先把概念明确一下, 再来看上面的代码, 会很简单的: 1. 对象都有一个类型, 类也是一个对象, 因此类也有一个类型, 类的类型, 或者叫类的类, 就是元类. 调用元类的构造函数来实例化出来的对象是一个类. 2. 在 Python 里面用 class XXX : pass 来定义一个类的时候, 其实也是调用元类的构造函数来实例化一个对象的. 3. 定义一个类的时候, 它的元类按以下方法来确定: (1). 如果类中有 __metaclass__ 属性, 则使用它来指定元类. (2). 如果类有父类, 并且父类有元类, 则使用父类的元类. 即使用父类的 __class__ 属性. (3). 类所在模块的 __metaclass__ 属性. 或者说全局的 __metaclass__ 变量. (4). 旧风格的 types.ClassType (5). 使用 type 作为元类. 好了, 现在我们来看上面的代码,

class FromMeta(type):
    def __init__(cls, name, base, attr):
        print 'FormMeta init'
        type.__init__(cls, name, base, attr)
通过继承 type 定义了一个元类, 这没什么好说的, 相信楼主的疑惑也不在这里.

class Form(FromMeta('base', (baseform,), {"name":'jiangnan'})):
    def __init__(self):
        print 'Form init'
这里 FromMeta('base', (baseform,), {"name":'jiangnan'}) 通过实例化一个元类来创建了一个类. 使用元类来实例化一个类对象, 当然会调用它的 __init__ 函数了, 所以输出第一个 FormMeta init 了. 然后, class Form 语句会创建一个类对象. 它使用哪个元类来创建呢? 根据上面说的, 会查找基类的 __class__ 属性. 使用 print FromMeta('base', (baseform,), {"name":'jiangnan'}).__class__ 可以查看到, 它的 __class__ 就是 FromMeta, 也就是说, Form 也会通过实例化 FromMeta 来创建. 所以, 这里就输出了第二个 FormMeta init 了. 同理, 对于 class loginForm 来说, 它的基类是 Form, 通过 print Form.__class__ 可以看到它的元类也是 FormMeta, 所以, loginForm 也是 FormMeta 实例化出来的, FormMeta 实例化对象的时候调用它的 __init__ 就输出了第三个 FormMeta init 了. 这三个 FormMeta init 的输出是和 a = loginForm() 无关的. 去掉它一样会输出前面的三个 FormMeta init. 不知道我说清楚了没有?
嗯 清楚了
www_adintr_com 2013-07-19
  • 打赏
  • 举报
回复
首先把概念明确一下, 再来看上面的代码, 会很简单的: 1. 对象都有一个类型, 类也是一个对象, 因此类也有一个类型, 类的类型, 或者叫类的类, 就是元类. 调用元类的构造函数来实例化出来的对象是一个类. 2. 在 Python 里面用 class XXX : pass 来定义一个类的时候, 其实也是调用元类的构造函数来实例化一个对象的. 3. 定义一个类的时候, 它的元类按以下方法来确定: (1). 如果类中有 __metaclass__ 属性, 则使用它来指定元类. (2). 如果类有父类, 并且父类有元类, 则使用父类的元类. 即使用父类的 __class__ 属性. (3). 类所在模块的 __metaclass__ 属性. 或者说全局的 __metaclass__ 变量. (4). 旧风格的 types.ClassType (5). 使用 type 作为元类. 好了, 现在我们来看上面的代码,

class FromMeta(type):
    def __init__(cls, name, base, attr):
        print 'FormMeta init'
        type.__init__(cls, name, base, attr)
通过继承 type 定义了一个元类, 这没什么好说的, 相信楼主的疑惑也不在这里.

class Form(FromMeta('base', (baseform,), {"name":'jiangnan'})):
    def __init__(self):
        print 'Form init'
这里 FromMeta('base', (baseform,), {"name":'jiangnan'}) 通过实例化一个元类来创建了一个类. 使用元类来实例化一个类对象, 当然会调用它的 __init__ 函数了, 所以输出第一个 FormMeta init 了. 然后, class Form 语句会创建一个类对象. 它使用哪个元类来创建呢? 根据上面说的, 会查找基类的 __class__ 属性. 使用 print FromMeta('base', (baseform,), {"name":'jiangnan'}).__class__ 可以查看到, 它的 __class__ 就是 FromMeta, 也就是说, Form 也会通过实例化 FromMeta 来创建. 所以, 这里就输出了第二个 FormMeta init 了. 同理, 对于 class loginForm 来说, 它的基类是 Form, 通过 print Form.__class__ 可以看到它的元类也是 FormMeta, 所以, loginForm 也是 FormMeta 实例化出来的, FormMeta 实例化对象的时候调用它的 __init__ 就输出了第三个 FormMeta init 了. 这三个 FormMeta init 的输出是和 a = loginForm() 无关的. 去掉它一样会输出前面的三个 FormMeta init. 不知道我说清楚了没有?
马尾 2013-07-18
  • 打赏
  • 举报
回复
lz。类能继承实例吗?还有class fromMeta(type),type又是什么啊?这是3.0的写法吗?为什么我看书的时候都没看到这种写法?PS:新手!
hsfzxjy 2013-07-10
  • 打赏
  • 举报
回复
这个很奇怪。。不过我改一下代码: b=FromMeta('base', (baseform,), {"name":'jiangnan'}) class Form(b): def __init__(self): print 'Form init' 执行a = loginForm()便只输出:loginForm init

37,719

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧