Python中的类,构造方法,元类

栏目: Python · 发布时间: 6年前

内容简介:Python中的类,构造方法,元类

摘要

如无特殊说明,Python的版本都是2.X。

Python中的类

Python中有两种类:经典类 和 新式类。

新式类直接或间接继承自object类,也就是说新式类都是object类的子类;其他的类都是经典类。

# coding: utf8
import types

class Classic:
    pass

class NewStyle(object):
    def __new__(cls, *a, **kw):
        instance = super(NewStyle, cls).__new__(cls, *a, **kw)
        return instance

    def __init__(self, *a, **kw):
        pass

if __name__ == "__main__":
    # 经典类是ClassType类型的
    print isinstance(Classic, types.ClassType) # True

    # 新式类是TypeType类型的
    print isinstance(NewStyle, types.TypeType) # True

    # 经典类 和 新式类的 mro 顺序也是不一样的

    # 经典类的实例是InstanceType类型的,新式类的实例不是
    print type(Classic()) == types.InstanceType # True
    print type(NewStyle()) == types.InstanceType # False

新式类的构造方法

新式类有2个与对象构造相关的魔术方法:

  • __init__(self, ...)
  • __new__(cls, ...)

大多数人会以为 __init__ 方法是构造方法,其实不然。 __init__ 方法其实可以叫做 初始化方法 ,它的作用是在对象被创建!!!之后!!!,对对象的属性进行初始化。新式类的真正的构造方法是 __new__ 方法, __new__ 方法是一个静态方法,哪怕在定义它的时候,并没有使用 @staticmethod 装饰器。

[root@iZj6chejzrsqpclb7miryaZ ~]# cat test.py 
# coding: utf8

class NewStyle(object): # 注意:一定要是新式类
    def __new__(cls, *a, **kw):
        print 'instance will be created...'
        # 调用父类的 构造方法 
        instance = super(NewStyle, cls).__new__(cls, *a, **kw)
        print 'instance is created...'

        return instance

    def __init__(self, *a, **kw):
        print '__init__ is invoked...'

if __name__ == "__main__":
    print NewStyle()
[root@iZj6chejzrsqpclb7miryaZ ~]# python test.py 
instance will be created...
instance is created...
__init__ is invoked...
<__main__.NewStyle object at 0x7f0e1b255690>

如果本类中,没有定义 __new__ 构造方法,那么会去父类中找;...,一直到object类。

通常情况下,很少使用 __new__ 方法。在使用元类的时候,会用到 __new__ 方法。

元类

Python 中一切皆对象。类的实例是对象, 类本身也是对象 。类是用来创建对象的,而 元类是用来创建类的

下面看一下,我们怎么在Python创建类:

[root@iZj6chejzrsqpclb7miryaZ ~]# cat test.py 
class MyClass1(object):
    @staticmethod
    def sm():
        print "sm() in MyClass1"

print MyClass1
MyClass1.sm()

def sm():
    print "sm() in MyClass2"
MyClass2 = type("MyClass2", (object,), {"sm": staticmethod(sm)})

print MyClass2
MyClass2.sm()
[root@iZj6chejzrsqpclb7miryaZ ~]# python test.py 
<class '__main__.MyClass1'>
sm() in MyClass1
<class '__main__.MyClass2'>
sm() in MyClass2

我们可以看到,第一种是定义类的标准语法,使用 class 关键字;第二种使用了 type 这个类(!!! type 不是内建方法,是一个类,而且是所有新式类的最终的元类,也就是说所有的新式类,都是type的实例,都是通过type创建的!!!)。

下面看一个例子:

# coding: utf8

class NewStyle(object):
    pass

# 新式类的__class__属性,指向其元类
print NewStyle.__class__ == type # True

# 新式类的对象的__class__属性,指向创建它的类
print NewStyle().__class__ == NewStyle # True

下面,看一个使用元类的例子:

[root@iZj6chejzrsqpclb7miryaZ ~]# cat test.py 
# coding: utf8

import types

def log_deco(f):
    def _inner(*a, **kw):
        print "enter"
        try:
            return f(*a, **kw)
        finally:
            print "exit"
    return _inner

class MetaClass1(type): # 注意:继承type类,而不是object类
    def __new__(cls, name, bases, attrs):
        # 我们可以在这里做一些hack。比如给类中所有的方法
        # + 都加上一个打印日志的装饰器
        for attr_name, attr in attrs.iteritems():
            if isinstance(attr, types.FunctionType):
                attrs[attr_name] = log_deco(attr)

        # 调用父类的__new__方法,最终会调用到type.__new__方法
        clazz = super(MetaClass1, cls).__new__(cls, name, bases, attrs)
        print "class is created at: %r" % clazz
        return clazz

class MyClass1(object):
    # 通过__metaclass__类属性,为类指定元类
    __metaclass__ = MetaClass1

    def method(self):
        print "I am method() in MyClass1"

# 类是元类的对象~
print isinstance(MyClass1, MetaClass1) # True

# 类的实例是类的对象
print isinstance(MyClass1(), MyClass1) # True


print "==="
MyClass1().method()
print "==="
[root@iZj6chejzrsqpclb7miryaZ ~]# python test.py 
class is created at: 
<class __main__="" myclass1="">
 
True
True
===
enter
I am method() in MyClass1
exit
===

</class>

在新式类中,如果类本身没通过 __metaclass__ 指定元类,那么则去父类找;...,一直到object,object的元类是type。


以上所述就是小编给大家介绍的《Python中的类,构造方法,元类》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

乔纳森传

乔纳森传

利恩德·卡尼 / 汪琪 岳卉 王文雅 / 中信出版社 / 2014-1-1 / 49

抛开苹果公司,单就设计行业来讲,乔纳森也是一个特殊的人物。他推动了设计行业的大变革:不再为产品增加看起来炫得多的配件,而是要去掉多余的东西。 ——陈向东 终于有一本书能够如此地接地气:它不再关注那位神一样的乔布斯,而是关注那位站在神的背后,同样具有神一样光环的乔纳森。 ——孙陶然 乔纳森•艾夫把他自己对科学、人文、艺术,乃至整个世界的感知尽数渗透进苹果的设计和审美之中,他是......一起来看看 《乔纳森传》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

随机密码生成器
随机密码生成器

多种字符组合密码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具