美文网首页
python metaclass

python metaclass

作者: halfempty | 来源:发表于2018-11-07 12:51 被阅读0次

1 类亦为对象

class Person():
    name = "Rocky"
    age = 18
    
    def __init__(self, weight):
        self.weight = weight
        
In[5]: person = Person(48)

In[6]: print(person)
<__main__.Person object at 0x00000277A5FC8DA0>

In[7]: print(Person)
<class '__main__.Person'>

In[8]: isinstance(person, Person)
Out[8]: True

一般情况下,我们称Person为类(class),通过Person(48)实例化的person为对象(object);二者之间的关系为:person是Person的实例,即Person可以创建person

然而在OOP的世界里,万事皆对象,其中也包括class,那么又是谁创造了class呢?

In[9]: Person.__class__
Out[9]: type

In[10]: isinstance(Person, type)
Out[10]: True

In[12]: type.__class__
Out[12]: type

In[13]: isinstance(type, type)
Out[13]: True

没错,正是type

2 对象的性质

既然类是对象,那么它理应有对象的特质:

  • 赋值给变量
  • 支持复制
  • 增加属性
  • 充当方法的参数
In[17]: Man = Person
In[18]: man = Man(48)
In[19]: print(man)
<__main__.Person object at 0x00000277A5FF3048>

In[20]: Man.sex = "male"

In[25]: import copy
In[26]: Man_copy = copy.copy(Man)
In[27]: print(Man_copy)
<class '__main__.Person'>

所以类属性、类方法从某种意义上讲,依然是对象的属性、对象的方法

3 创建类对象

类是type的实例,那看看type是如何创建类的

对于type的用法,可以偏向于type(person),查看对象的类型,显然这并不是创建类的正确方式

class type(object):

    def __init__(cls, what, bases=None, dict=None): # known special case of type.__init__
        """
        type(object_or_name, bases, dict)
        type(object) -> the object's type
        type(name, bases, dict) -> a new type
        # (copied from class doc)
        """
        pass

type(name, bases, dict) -> a new type正是我们寻找的方法

其中name表示类对象名称,bases表类继承的父类(tuple),dict表示类的属性和方法的映射

# 使用type重新创建Person类

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

Person = type("Person", (), {'name':"Rocky", 'age':18, '__init__': __init__})

4 自定义metaclass

首先看一下metaclass在python3中的使用:

class Person(object, metaclass=something):
    pass
    
# 在python2中是使用__metaclass__属性

比如,我们希望将类的属性转换成大写

from inspect import isfunction


class Base(type):
    # @classmethod
    # def __prepare__(metacls, cls, bases):
    #     return dict()

    def __new__(metacls, cls, bases, namespace):
        upper_namespace = {}
        for k, v in namespace.items():
            if not isfunction(v) and not k.startswith('__'):
                upper_namespace[k.upper()] = v
            else:
                upper_namespace[k] = v
        return super().__new__(metacls, cls, bases, upper_namespace)


class Person(metaclass=Base):
    name = "Rocky"
    age = 18

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


if __name__ == "__main__":
    print(Person.__dict__)
    
# {'__module__': '__main__', 'NAME': 'Rocky', 'AGE': 18, '__init__': <function Person.__init__ at 0x000001D804B16598>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}

关于metaclass的应用,可以参考Django中的ModelBase

相关文章

  • 面试常考(python)

    Python语言特性 1.Python的函数参数传递 2.元类 metaclass metaclass 允许创建类...

  • 一文搞懂什么是Python的metaclass

    Python 有很多黑魔法,为了不分你的心,今天只讲 metaclass。对于 metaclass 这种特性,有两...

  • python metaclass

    1 类亦为对象 一般情况下,我们称Person为类(class),通过Person(48)实例化的person为对...

  • Python(metaclass)

    示例代码 参考 Customizing class creation Basic customization

  • python:metaclass

    metaclass翻译过来应该是元类的意思。python中一切皆是对象,连类也是对象 而类是元类的实例,默认的cl...

  • python metaclass ..

    目录 要点回顾第一:everything is object第二:metaclass可以定制类的创建第三:关于me...

  • interview_python

    Python语言特性1 Python的函数参数传递2 Python中的元类(metaclass)3 @static...

  • metaclass

    深刻理解Python中的元类(metaclass) - 文章 - 伯乐在线

  • Python Metaclass 初探

    先以一个大牛的一段关于Python Metapgramming的著名的话来做开头: Metaclasses are...

  • Python MetaClass参考

    一:类也是对象 类就是一组用来描述如何生成一个对象的代码。 类也是一个对象,只要你使用关键字 class,pyth...

网友评论

      本文标题:python metaclass

      本文链接:https://www.haomeiwen.com/subject/pbaatqtx.html