类也是对象
在 python 中, 一切皆是对象, 就连生成对象的类, 自身也是一个对象. 既然类也是一个对象, 那么类也可以被作为参数传递, 也可以赋值给其他变量...
- In [1]: class Cat(object):
- ...: pass
- ...:
- ...:
- In [2]: kitty = Cat()
- In [3]: kitty
- Out[3]: <__main__.Cat at 0x106886eb8>
- In [4]: Cat
- Out[4]: __main__.Cat
- In [5]: def echo(o):
- ...: print(o)
- ...:
- In [6]: echo(Cat) # 类作为参数
- <class '__main__.Cat'>
- In [7]: hasattr(Cat, 'color')
- Out[7]: False
- In [8]: Cat.color = 'yellow' # 动态添加类的属性
- In [9]: hasattr(Cat, 'color')
- Out[9]: True
- In [10]: Cat.color
- Out[10]: 'yellow'
- In [11]: CatMirror = Cat # 将类赋值给变量
- In [12]: CatMirror
- Out[12]: __main__.Cat
动态地创建类
- In [13]: def choose_class(name):
- ...: if name == 'cat':
- ...: class Cat(object):
- ...: pass
- ...: return Cat # 返回的是类, 而不是类的实例
- ...: else:
- ...: class Dog(object):
- ...: pass
- ...: return Dog
- ...:
- In [17]: obj1 = choose_class('cat')
- In [18]: obj1
- Out[18]: __main__.choose_class.<locals>.Cat
- In [19]: obj2 = choose_class('dog')
- In [20]: obj2
- Out[20]: __main__.choose_class.<locals>.Dog
用 type 创建类
type 可以查看一个对象的类型
- In [21]: type(1)
- Out[21]: int
- In [22]: type('hello')
- Out[22]: str
- In [23]: type(Cat)
- Out[23]: type
- In [24]: type(int)
- Out[24]: type
- In [25]: type(str)
- Out[25]: type
- In [26]: type(type)
- Out[26]: type
如果往上追溯类的来源, 得到的都是 type, 说明 type 是元类, 即一切类的始祖
既然如此, 我们可以直接使用 type 创建类
格式如下:
type('类名',(由父类名称组成的元组), {包含属性的字典})
用 type 创建 Cat 类
- In [27]: Cat = type("Cat", (), {})
- In [28]: Cat
- Out[28]: __main__.Cat
- In [29]: Cat()
- Out[29]: <__main__.Cat at 0x106950208>
- In [30]: type(Cat)
- Out[30]: type
创建带有属性的类
- In [32]: Cat = type('Cat', (), {'color': 'white'})
- In [33]: Cat.color
- Out[33]: 'white'
metaclass 属性
如果在定义一个类时为其添加 metaclass 属性, python 就会用元类来创建类.
当程序在执行以下代码时, 流程是这样的:
- class Cat(Animal):
- pass
Cat 中若有 metaclass 属性, 就通过 metaclass 创建一个名为 Cat 的类
如果在 Cat 中没找到 metaclass, 继续向其父类 Animal 寻找 metaclass
如果在父类中都找不到 metaclass, 会在模块层次中去寻找 metaclass
如果最终找不到 metaclass,python 就会用内置的 type 来创建这个类
- # -*- coding: UTF-8 -*-
- def upper_attr(future_class_name, future_class_parents, future_class_attr):
- # 遍历属性字典, 将不是__开头的属性名称改为大写
- newAttr = {}
- for name, value in future_class_attr.items():
- newAttr[name.upper()] = value
- # 使用 type 创建类
- return type(future_class_name, future_class_parents, newAttr)
- class Foo(object, metaclass=upper_attr):
- bar = 'bip'
- print(hasattr(Foo, 'bar')) # False
- print(hasattr(Foo, 'BAR')) # True
- f = Foo()
- print(f.BAR) # bip
元类到底有什么用
以上只是关于元类的一些粗浅认知, 元类的作用主要是:
拦截类的创建
修改类
返回修改之后的类
元类在日常开发中极少会用到, 属于深度的魔法. 如无必要, 了解其概念即可.
元类
来源: http://www.jianshu.com/p/4ec17bcdb783