python总结(六):元类与方法的默认实现

通过元类,可以修改类的方法与实现,根据“_ init_”与“_ new_”方法钩子的不同,可以在类创建后与类创建前添加控制,在类创建前可提供默认实现,在类创建后可以提供方法检查、属性检查与覆盖实现。

在大部分的情况下,通过继承可以实现元类的大部分功能,所以在99%的情况下,元类基本都用不上,但是需要对类自身进行操作时,元类就排上了用场,下面是具体步骤。

1. 创建元类

元类必须要继承types,或者是其他元类,如下:

class MetaClass(type):

    #   在类创建前调用
    def __new__(cls, name, bases, attrs):
        def sayHello(self):
             print 'Hello, %s' %(self.username)
        #   添加实例方法
        cls.sayHello = sayHello 
        return super(MetaClass, cls).__new__(cls, name, bases, attrs)

     #   在类创建后调用,这里的self指向带创建的类
    def __init__(self, name, bases, attrs):
        #   添加静态方法
        def add(a, b):
            return a + b
        #   添加类方法    
        def adds(cls, a, b):
            return a + b
        self.add = staticmethod(add)
        self.adds = classmethod(adds)
        super(MetaClass, self).__init__(name, bases, attrs)

#  元类也可以继承
class DomainMeta(MetaClass):
    pass

在上面的代理里,需要总结的有:
1. “_ new_”提供默认实现(优先级最低),记住一定要有返回值;
2. “_ init_”会覆盖类的定义(优先级最高);
3. 类方法与静态方法的区别在于参数数量,类方法第一个参数为类对象自身,而静态则没有第一个参数;

2. 使用元类

使用元类非常简单,只要在创建类时指定“_ metaclass_”属性即可,如下:

class Person(object):
    __metaclass__ = DomainMeta

    def __init__(self, username):
        self.username = username

    def sayHello(self):
        print 'Hi, %s' %(self.username)

通过“_ metaclass_”属性,类获得了元类中定义的方法,包括静态方法、类方法以及实例方法,如下:

yiifaa = Person('yiifaa')
#  会被类中的定义方法覆盖
yiifaa.sayHello()
#  静态方法
print Person.add(2, 3)
#  类方法
print Person.adds(5, 5)

结论

与继承相比,元类会满足如下条件(继承刚好相反):
1. 类是它的实例。

#   输出True
print isinstance(Person, DomainMeta)
  1. 元类与类不存在继承关系。
#   输出False
print issubclass(Person, DomainMeta)
  1. 元类与类通过“_ class_”建立关系。
#   输出True
print Person.__class__ == DomainMeta

最后,type是所有类的祖先节点,包括元类。

#   输出True 
print Person.__class__.__class__ == type
#   输出True 
print isinstance(Person, type)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值