zhangchaoyang

使用type创建类

使用type创建类的语法为

type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))

举个例子

class A(object):
    name=\'orisun\'

class B(object):
    city=\'BeiJing\'

class C(A,B):
    country=\'CN\'

if __name__ == \'__main__\':
    c=C()
    print c.__class__.__name__
    print type(c)
    print type(c.__class__)
    print dir(c)
    print 

    d=type(\'C\',(A,B,),{\'country\':\'CN\'})
    print d.__name__
    print type(d)
    print dir(d)

输出

C
<class \'__main__.C\'>
<type \'type\'>
[\'__class__\', \'__delattr__\', \'__dict__\', \'__doc__\', \'__format__\', \'__getattribute__\', \'__hash__\', \'__init__\', \'__module__\', \'__new__\', \'__reduce__\', \'__reduce_ex__\', \'__repr__\', \'__setattr__\', \'__sizeof__\', \'__str__\', \'__subclasshook__\', \'__weakref__\', \'city\', \'country\', \'name\']

C
<type \'type\'>
[\'__class__\', \'__delattr__\', \'__dict__\', \'__doc__\', \'__format__\', \'__getattribute__\', \'__hash__\', \'__init__\', \'__module__\', \'__new__\', \'__reduce__\', \'__reduce_ex__\', \'__repr__\', \'__setattr__\', \'__sizeof__\', \'__str__\', \'__subclasshook__\', \'__weakref__\', \'city\', \'country\', \'name\']

在python中一切皆对象,类也是对象,从上面的例子我们看到type(obj)是一个class,但是只要在这个class上继续调用type(),就会发现它最终还是个type。可以说pyhton中的所有对象(包括类)都是type创建出来的。下文我们会讲到使用MetaClass可以创建类(注意是创建类,不是对象哦),而MetaClass内部实际上还是调用的type。

使用MetaClass创建类

class Foo(object):
    __metaclass__=something

当定义了一个类时,python会经历以下步骤来确定如何创建一个对象。

  1. 如果类中指定了__metaclass__,则使用__metaclass__来创建对象。否则进入第2步
  2. 延着继承链从基类中找__metaclass__,如果找到了就使用该__metaclass__来创建对象。否则进入第3步
  3. 使用内置的type来创建对象

归根到底,能够创建对象的只有type,所以我们要自定义一个__metaclass__只有2个办法:

  1. 调用type函数
  2. 自己实现一个type的子类

使用type函数创建__metaclass__

def upper_attr(class_name,base_classes,attr_dict):
    \'\'\'返回一个类对象,将属性都转化为大写
    \'\'\'
    #选择所有不以\'__\'开头的属性
    attrs=((name,value) for name,value in attr_dict.items() if not name.startswith(\'__\'))
    #将它们转换为大写
    uppercase_attr=dict((name.upper(),value) for name,value in attrs)
    #通过type来创建类对象
    return type(class_name,base_classes,uppercase_attr)


class A(object):
    __metaclass__=upper_attr
    name=\'orisun\'

if __name__ == \'__main__\':
    print hasattr(A,\'name\')         #输出False
    print hasattr(A,\'NAME\')         #输出True

创建type的子类来实现__metaclass__

class UpperMetaClass(type):
    def __new__(cls,class_name,base_classes,attr_dict):
        attrs=((name,value) for name,value in attr_dict.items() if not name.startswith(\'__\'))
        uppercase_attr=dict((name.upper(),value) for name,value in attrs)
        return type.__new__(cls,class_name,base_classes,uppercase_attr)
        #等价于:
        #return super(UpperMetaClass,cls).__new__(cls,class_name,base_classes,uppercase_attr)
   
class A(object):
    __metaclass__=UpperMetaClass
    name=\'orisun\'

if __name__ == \'__main__\':
    print hasattr(A,\'name\')         #输出False
    print hasattr(A,\'NAME\')         #输出True

 其实在MetaClass中定义__new__或__init__或__call__都可以实现对创建类的操控。具体原因参见:python对象的创建和销毁

在MetaClass中定义__getattribute__、__getattr__、__setattr__可以影响“通过类对属性的访问和设置

分类:

技术点:

相关文章: