[Python]元类和__metaclass__

本文介绍了元类的基本概念及其在Python中的应用。通过两个实例演示了如何使用元类来控制类的创建过程,包括类的初始化及特定方法的覆盖。

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

一、元类是什么

        元类让你来定义某些类是如何被创建的,从根本上说,赋予你如何创建类的控制权(你甚至不用去想类实例层面的东西)。从根本上说,你可以把元类想成一个类中类,或是一个类,它的实例是其他类。

二、使用元类

        元类一般用于创建类。在执行类定义时,解释器必须要知道这个类的正确的元类。解释器会先寻找类属性__metaclass__,如果此属性存在,就将这个属性赋值给此类作为它的元类。如果此属性没有定义,它会向上查找父类中的__metaclass__。所有新风格的类如果没有任何父类,会从对象或类型中继承(type(object)当然是类型)。如果还没有发现__metaclass__属性,解释器会检查名字为__metaclass__的全局变量;如果它存在,就使用它作为元类。否则,这个类就是一个传统类,并用types.ClassType作为此类的元类。(注意:在这里你可以运用一些技巧……如果你定义了一个传统类,并且设置它的__metaclass__=type,并且你是在将它升级为一个新风格的类)。

        在执行类定义的时候,将检查此类的正确的(一般是默认的)元类,元类(通常)传递三个参数(到构造器):类名、从基类继承数据的元组和(类的)属性字典。

元类实例一:

#! /usr/bin/env python
#coding=utf-8
from time import ctime

print "*** welcom to metaclasses!"
print "\tmetaclass declartion first."

class  MetaC(type):
    def __init__(cls,name,bases,attrdict):
        super(MetaC,cls).__init__(name,bases,attrdict)
        print "*** Created class %r at : %s"%(name,ctime())
        
print '\tClass "Foo" declaration next.'
class Foo(object):
    __metaclass__ = MetaC
    def __init__(self):
        print "*** Instantiated class %r at :%s" %(
        self.__class__.__name__,ctime())

print '\tClass "Foo" instantiation next.'
f = Foo()
print "\tDone."
>>>

*** welcom to metaclasses!
metaclass declartion first.
Class "Foo" declaration next.
*** Created class 'Foo' at : Mon Jul 21 22:57:15 2014
Class "Foo" instantiation next.
*** Instantiated class 'Foo' at :Mon Jul 21 22:57:15 2014
Done.

元类实例二:

from warnings import warn
class ReqStrSugRepr(type):
    
    def __init__(cls,name,bases,attrd):
        super(ReqStrSugRepr,cls).__init__(name,bases,attrd)
        
        if '__str__' not in attrd:
            raise TypeError("Class requires overiding of __str__()")
        
        if '__repr__' not in attrd:
            warn("Class suggests overriding of __repr__()\n",stacklevel=3)
            
print "*** Defined ReqStrSugRepr(meta) class."

class Foo(object):
    __metaclass__ = ReqStrSugRepr
    def __str__(self):
        return "Instance of class:",\
        self.__class__.__name__
    def __repr__(self):
        return self.__class__.__name__
    
print "*** Defined Foo class. #both __str__ and __repr__ defined."

class Bar(object):
    __metaclass__ = ReqStrSugRepr
    
    def __str__(self):
        return "Instance of class:",\
        self.__class__.__name__
        
print "*** Defined Bar class. # no __repr__ defined."

class FooBar(object):
    __metaclass__ = ReqStrSugRepr
    
print "*** Defined FooBar class.# no __str__ or __repr__ defined."

>>>

*** Defined ReqStrSugRepr(meta) class.

*** Defined Foo class. #both __str__ and __repr__ defined.
*** Defined Bar class. # no __repr__ defined.
sys:1: UserWarning: Class suggests overriding of __repr__()


Traceback (most recent call last):
  File "E:\Papanikolaou\Python\MetaClassPractice.py", line 59, in <module>
    class FooBar(object):
  File "E:\Papanikolaou\Python\MetaClassPractice.py", line 33, in __init__
    raise TypeError("Class requires overiding of __str__()")
TypeError: Class requires overiding of __str__()

REF:Core Python Programming



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值