Python学习笔记(27),type和metaclass

type()

动态语言的函数和类的定义,不是编译时定义的,而是运行时动态创建的
例如:Hello class定义在hello.py模块中。

class Hello:
    def hello(self, name='world'):
        print('Hello, %s.' % name)

当Python解释器载入模块时,就会依次执行该模块的所有语句,执行结果就是动态地创建出Hello的class对象

print(type(Hello))
h = Hello()
print(type(h))
<class 'type'>
<class '__main__.Hello'>

Hello是一个class,它的类型就是typeh是一个实例,它的类型就是class '__main__.Hello'>,因为此处Hellomain模块中,没有保存在hello.py`模块。

type()不仅能返回一个对象的类型,还可以用type()函数创建一个类,由于实际使用时,和直接用class来定义类是完全一样的,不做赘述。

def fn(self, name='world'):
    print('Hello, %s!' % name)

Hello = type('Hello', (object,), dict(hello=fn))
h = Hello()
h.hello()
print(type(h))
print(type(type(h)))
Hello, world!
<class '__main__.Hello'>
<class 'type'>

metaclass

metaclass直译为元类,metaclass能创建类,先定义metaclass,然后创建类,最后创建实例。

metaclass可以应用于ORM框架的编写,先mark等到实战用到时再详细阅读补充。

class ListMetaclass(type):
    def __new__(cls, name, bases, attrs):
        attrs['add'] = lambda self, value: self.append(value)
        print('in ListNetaclass __new__(), cls = %s, name = %s, bases = %s\n' % (cls, name, bases))
        for attr in attrs:
            print(attr)
        return type.__new__(cls, name, bases, attrs)

class MyList(list, metaclass=ListMetaclass):
    a = 1
    print('in mylist class')
    
    def __init__(self):
        print('in __init__()\n')
    
    def fn():
        pass
    
l = MyList()
print(dir(l))
l.add(1)
in mylist class
in ListNetaclass __new__(), cls = <class '__main__.ListMetaclass'>, name = MyList, bases = (<class 'list'>,)

__module__
__qualname__
a
__init__
fn
add
in __init__()

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'add', 'append', 'clear', 'copy', 'count', 'extend', 'fn', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

从输出结果可以看书,运行顺序是,类先被赋值一些属性,保存在attrs dict中。因为有metaclass=ListMetaClass,先通过ListMetaClass中的__new__方法创建类,创建好类后,再调用MyList.__init__()构造器创建实例对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值