python metaclass

本文详细解析了Python中的元类概念,从类是对象、动态创建类、元类的作用到元类实例应用,以及如何通过__metaclass__属性自定义类创建方式,并以Django中的Model使用为例进行说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习python这么久对python的metaclass还是一知半解,网上找了找,发现stackoverflow太强大了: 
http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python
这个回答很详细,太厉害了,这里自己总结一下,免的忘记。

1. 类也是对象(class are object), 类在内存中也占有一段空间,所以

class Foo(object):pass
id(Foo) #有值
Foo.bar = 'bar'  #给类添加一个属性

2. 可以动态的创建类
type(class_name, class_parents, class_dict), 比如
def echo_bar(self): print self.bar
Foo = type('Foo', (object, ), {'bar':'bar', 'echo_bar', echo_bar})

3. metaclass是创建类的'stuff',一般也可以理解成对象是类创建的, 类是metaclass创建的。
type is the metaclass Python uses to create all classes behind the scenes.
Everything, and I mean everything, is an object in Python. That includes ints, strings, functions and classes. All of them are objects. And all of them have been created from a class.
You can call it a 'class factory' if you wish.
4. __metaclass__属性
可以给类添加__metaclass__属性,在创建类时, python会查找(在自身,子类,模块中)是否定义了__metaclass__,有则用之来创建类, 否则用type来创建类
所以可以通过定义__metaclass__来改变类的创建方式,__metaclass__可以是任何可执行的东西,所以不一定需要是类。 这里就直接引用他的例子了。

# the metaclass will automatically get passed the same argument
# that you usually pass to `type`
def upper_attr(future_class_name, future_class_parents, future_class_attr):
  """
    Return a class object, with the list of its attribute turned 
    into uppercase.
  """

  # pick up any attribute that doesn't start with '__'
  attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__'))
  # turn them into uppercase
  uppercase_attr = dict((name.upper(), value) for name, value in attrs)

  # let `type` do the class creation
  return type(future_class_name, future_class_parents, uppercase_attr)

__metaclass__ = upper_attr # this will affect all classes in the module

class Foo(object): 
  # we can define __metaclass__ here instead to affect only this class
  bar = 'bip'

print hasattr(Foo, 'bar')
# Out: False
print hasattr(Foo, 'BAR')
# Out: True

f = Foo()
print f.BAR
# Out: 'bip'

# remember that `type` is actually a class like `str` and `int`
# so you can inherit from it
class UpperAttrMetaclass(type): 
    # __new__ is the method called before __init__
    # it's the method that creates the object and returns it
    # while __init__ just initializes the object passed as parameter
    # you rarely use __new__, except when you want to control how the object
    # is created.
    # here the created object is the class, and we want to customize it
    # so we override __new__
    # you can do some stuff in __init__ too if you wish
    # some advanced use involves overriding __call__ as well, but we won't
    # see this
    def __new__(upperattr_metaclass, future_class_name, 
                future_class_parents, future_class_attr):

        attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__'))
        uppercase_attr = dict((name.upper(), value) for name, value in attrs)

        return type(future_class_name, future_class_parents, uppercase_attr)

class UpperAttrMetaclass(type): 

    def __new__(upperattr_metaclass, future_class_name, 
                future_class_parents, future_class_attr):

        attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__'))
        uppercase_attr = dict((name.upper(), value) for name, value in attrs)

        # reuse the type.__new__ method
        # this is basic OOP, nothing magic in there
        return type.__new__(upperattr_metaclass, future_class_name, 
                            future_class_parents, uppercase_attr)


Django中Model使用__metaclass__的例子

class Model(object):
     __metaclass__ = ModelBase
     _deferred = False
.....






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值