Python元類的一些應用

最近剛接觸python的元類,網絡上有比較詳細的介紹,這裏是在看Django時候發現一點關於元類的應用,作個筆記。python

from django.utils import six

class A(type):
    def __new__(cls, name, parents, attrs):
        return type.__new__(cls, name, parents, attrs)


class C(six.with_metaclass(A)):
    pass

建立C類的時候,他會先調用__metaclass__屬性裏面的東西。上面C類中的代碼能夠是django

class C(object):
    __metaclass__ = A


def with_metaclass(meta, *bases):
    """Create a base class with a metaclass."""
    # This requires a bit of explanation: the basic idea is to make a dummy
    # metaclass for one level of class instantiation that replaces itself with
    # the actual metaclass.
    class metaclass(meta):
        def __new__(cls, name, this_bases, d):
            return meta(name, bases, d)
    return type.__new__(metaclass, 'temporary_class', (), {})

若是咱們須要作一些小動做,能夠在這裏下手。
網絡


那麼如今就在A類繼承一個B類,在加上幾個新的變量。ssh

from django.utils import six

class A(type):
    def __new__(cls, name, parents, attrs):
        attrs['name'] = 'sora'
        attrs['sex'] = 'man'
        name = 'Hello'
        parents = (B,)
        return type.__new__(cls, name, parents, attrs)

class B(object):
    a = 123456

class C(six.with_metaclass(A)):
    pass

c = C()
print dir(c)
print c.name
print c.__class__
print c.a

輸出結果:ide

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'name', 'sex']學習

soraui

<class '__main__.Hello'>this

123456idea


parents是父類,attrs是一個字典,注意的是,attrs不能寫成{'name':'sora','sex':',man'}這樣是不對的.name是建立的類名字.code


這裏就是一些簡單的一些應用了,在Django裏面,常常要用到class Meta這個東西,Django相關的tastypie裏面也有,好比Resource類,看了一下源代碼學習了下.

#coding:utf-8
from django.utils import six

class B(object):
    opt_1 = 1
    opt_2 = 2
    opt_3 = 3

    def __new__(cls, meta=None):
        overrides = {}
        if meta:
            for override_name in dir(meta):
                if not override_name.startswith('_'):
                    overrides[override_name] = getattr(meta,override_name)

        return object.__new__(type(b'B',(cls,),overrides))


class A(type):
    def __new__(cls, name, bases, attrs):
        new_class = super(A,cls).__new__(cls,name,bases,attrs)
        # new_class = type.__new__(cls, name, bases, attrs)
        ops = getattr(new_class,'Options',None)
        new_class._opt = B(ops)

        return new_class


class C(six.with_metaclass(A)):
    def show_opt(self):
        opt = self._opt
        print 'opt_1:',opt.opt_1
        print 'opt_2:',opt.opt_2
        print 'opt_3:',opt.opt_3


class D(C):
    class Options:
        opt_1 = 5

d = D()
d.show_opt()

輸出結果:

opt_1: 5

opt_2: 2

opt_3: 3

Django裏面是class Meta,這裏換了下名字。

相關文章
相關標籤/搜索