python中自定义元类创建类对象的方式

新手上路,请多包涵

问题描述

BoardMeta是自定义元类,使用这个自定义元类创建了Board类,程序20行Board类不是已经创建过了吗?

#!/usr/bin/env python
# encoding: utf-8

_board_classes = {}                                                                                

class BoardMeta(type):                                                                            #元类                                            
    def __init__(cls, name, bases, dct):                                                            
        super(BoardMeta, cls).__init__(name, bases, dct)                                        #调用父类__init__()函数,父类是type(),用于创建类

        if 'abstract' not in cls.__dict__:                                                        #属性中不含有abstract返回true
            cls.abstract = False
            
        if cls.abstract:
            return

        board_name = getattr(cls, 'name', name)

        _board_classes[board_name] = cls

class Board(object):
    abstract = True                                                                                

    def __init__(self):                                                                            
        pass

Board = BoardMeta('Board', Board.__bases__, dict(Board.__dict__))                                #使用自定义元类BoardMeta动态创建类Board                        

class sitl(BoardMeta('Board', Board.__bases__, dict(Board.__dict__))):
    pass

class linux(Board):
    pass
    
class pxfplus(linux):
    pass
    
def list_boards():                    
    print(sorted(list(_board_classes.keys())))    

list_boards()

以上代码运行输出[sitl, linux, pxfplus],程序是怎么运行的呢?

阅读 1.8k
1 个回答

前面的class Board(object)是使用普通的方式创建的一个类名叫Borad,到了Board = BoardMeta('Board', Board.__bases__, dict(Board.__dict__))这一行,就是使用BoardMeta创建的一个新的类了(虽然也叫Board,并且父类用的是Board.__bases__,属性用的是dict(Board.__dict__),就相当于复制了一个Board一样,但它已经是一个新的类了)。


由于sitl, linux, pxfplus这三个类都是(新的那个)Board的子类,因此在创建这三个类的时候也会使用自定义的元类创建,在这个创建的过程中,就把类名做为key写到了_board_classes


可以加上如下代码,查看前后Boardtype

print(type(Board))
Board = BoardMeta('Board', Board.__bases__, dict(Board.__dict__))                                                      
print(type(Board))

打印结果如下:

<class 'type'>
<class '__main__.BoardMeta'>

说明第一个Board的元类是type,第二Board的元类是BoardMeta

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题