class Example(object):
pass
object1 = Example()
print(object1)
# prints '<__main__.Example object at 0x102e26990>'
print(Example)
# prints '<class '__main__.Example'>'
Example_Mirror = Example
print(Example_Mirror)
# prints '<class '__main__.Example'>'
def Dynamic_Class_Creater(name):
if name == 'name1':
class Class1(object):
pass
return Class1
else:
class Class2(object):
pass
return Class2
first = Dynamic_Class_Creater('name1')
print(first)
# prints '<class '__main__.Class1'>'
print(first())
# prints '<__main__.Class1 object at 0x105452e10>'
type()
创建这个 class object# prints '<type 'type'>'
print(type(Example()))
# prints '<class '__main__.Example'>'
type()
函数可以接收 class 的描述来作为参数并返回所生成的 class object。type
同时具有这两个迥异的功能是由于 Python 兼容性问题导致的,不做深究type(class_name, tuple_of_parent_class, dict_of_attribute_names_and_values)
tuple_of_parent_class
用来表示继承关系,可以为空。第三个参数用来描述要创建的 class 所应该具有的属性:Example = type('Example', (), {})
print(Example)
<class '__main__.Example'>
type
所接收的第一个参数 'Example
' 是该 class 的名称,同时我们使用了 Example
作为存储该 class object 引用的变量。二者可以不同,但一般不采用不同的名字从而使得代码更加复杂:Example = type('Example', (), {'val1': 1, 'val2': 2})
# 等价于
class Example(object):
val1 = 1
val2 = 2
#####################################################
ChildExample = type('ChildExample', (Example,), {})
# 等价于
class ChildExample(Example):
pass
def echo(self):
print(self.val1)
ChildExample = type('ChildExample', (Example,), {'echo': echo})
print(hasattr(Example, 'echo'))
# prints 'False'
print(hasattr(ChildExample, 'echo'))
# prints 'True'
ChildExample = type('ChildExample', (Example,), {})
def another(self):
print('another')
ChildExample.another = another
class = metaclass()
object = class()
age = 24
print(age.__class__)
# prints '<type 'int'>'
print(age.__class__.__class__)
# prints '<type 'type'>'
class Example(object):
__metaclass__ = something
[other statements...]
class Foo(Bar):
pass
上述代码中,
Python 首先在 Foo
中寻找是否存在 __metaclass__ 属性
Foo
的 class object__metaclass__ 且没用继承任何类
,Python将会寻找 MODULE 级别的 __metaclass__
__metaclass__
如果存在继承类且没有定义 __metaclass__ 属性,Python 会使用当前类的父类的 metaclass 来创建当前类
__metaclass__
属性并不会被子类继承。被子类继承的是父类的 metaclass,也就是父类的 __class__
属性,比如上面的例子中,Bar.__class__
将会被 Foo
继承Bar
定义了一个 __metaclass__
属性来创建 Bar
的 class object,那么 Bar
的子类(也就是 Foo)
并不会继承这一行为# the metaclass will automatically get passed the same argument
# that is passed to `type()`
def upper_attr(class_name, class_parents, class_attr):
'''Return a class object, with the list of its attribute turned into
uppercase.
'''
# pick up any attribute that doesn't start with '__' and turn it into uppercase.
uppercase_attr = {}
for name, val in class_attr.items():
if name.startswith('__'):
uppercase_attr[name] = val
else:
uppercase_attr[name.upper()] = val
# let `type` do the class creation
return type(class_name, class_parents, uppercase_attr)
class Foo(object):
# this __metaclass__ will affect the creation of this new style class
__metaclass__ = upper_attr
bar = 'bar'
print(hasattr(Foo), 'bar')
# prints 'False'
print(hasattr(Foo), 'BAR')
# print 'True'
f = Foo()
print(f.BAR)
# print 'bar'
class UpperAttrMetaclass(type):
def __new__(cls, cls_name, bases, attr_dict):
uppercase_attr = {}
for name, val in attr_dict.items():
if name.startswith('__'):
uppercase_attr[name] = val
else:
uppercase_attr[name.upper()] = val
return super(UpperAttrMetaclass, cls).__new__(cls, cls_name, bases, uppercase_attr)
class Person(models.Model):
name = models.CharField(max_length=30)
age = models.IntegerField()
guy = Person(name='bob', age='35')
print(guy.age)
# prints '35'
IntegerField
对象,而是会返回一个 int
,甚至可以直接从数据库中调用这个值models.Model
定义了 __metaclass__
,并使用了一些操作来将我们使用简单的语句定义的 Person
转化成了与数据库相应的域相联系的类,这种逻辑才成为可能