在其他语言中我们都知道类和int,string等类型一样是用来生成对象的。
类就是生成对象的代码段。
在python中任然是这样,但是Python中的类还远不止如此,在python中类也是对象。只是这个对象拥有创建对象的能力。
但是,它的本质仍然是一个对象,于是乎你可以对它做如下的操作:
-
你可以将它赋值给一个变量
-
你可以拷贝它
-
你可以为它增加属性
-
你可以将它作为函数参数进行传递
同时因为类就是对象,所以可以在运行时动态的创建。
def choose_class(name):
… if name == 'foo':
… class Foo(object):
… pass
… return Foo # 返回的是类,不是类的实例
… else:
… class Bar(object):
… pass
… return Bar
…
>>> MyClass = choose_class('foo')
>>> print MyClass # 函数返回的是类,不是类的实例
<class '__main__'.Foo>
>>> print MyClass() # 你可以通过这个类创建类实例,也就是对象
<__main__.Foo object at 0x89c6d4c>
由于类也是对象,所以它们必须是通过什么东西来生成的才对。当你使用class关键字时,Python解释器自动创建这个对象。
使用type来创建类
我们都知道python中的自身,使用type可以知道当前变量的类型
print type(1)
<type 'int'>
print type("1")
<type 'str'>
type可以这样使用
type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
比如用type来创建下面的一个类
class Foo(object):
bar = True
使用type简化创建
Foo = type('Foo', (), {'bar':True})
使用继承,
在创建一个下面的子类
class FooChild(Foo):
… pass
FooChild = type('FooChild', (Foo,),{})
print FooChild
<class '__main__.FooChild'>
print FooChild.bar # bar属性是由Foo继承而来
True
使用type为你的类增加方法
def echo_bar(self):
print self.bar
FooChild = type('FooChild', (Foo,), {'echo_bar': echo_bar})
hasattr(Foo, 'echo_bar')
False
hasattr(FooChild, 'echo_bar')
True
my_foo = FooChild()
my_foo.echo_bar()
True
已定义的元类
==type==就是Python在背后用来创建所有类的元类。除此外还有==str==,==int==等内件元类
创建自己的元类
你可以在写一个类的时候为其添加metaclass属性。
class Foo(object):
__metaclass__ = something…
Foo中有metaclass这个属性吗?如果是,Python会在内存中通过metaclass创建一个名字为Foo的类对象。如果Python没有找到metaclass,它会继续在Bar(父类)中寻找metaclass属性,并尝试做和前面同样的操作。如果Python在任何父类中都找不到metaclass,它就会在模块层次中去寻找metaclass,并尝试做同样的操作。如果还是找不到metaclass,Python就会用内置的type来创建这个类对象。
比如将属性全部转化为大写
# 元类会自动将你通常传给‘type’的参数作为自己的参数传入
def upper_attr(future_class_name, future_class_parents, future_class_attr):
'''返回一个类对象,将属性都转为大写形式'''
# 选择所有不以'__'开头的属性
attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__'))
# 将它们转为大写形式
uppercase_attr = dict((name.upper(), value) for name, value in attrs)
# 通过'type'来做类对象的创建
return type(future_class_name, future_class_parents, uppercase_attr)
__metaclass__ = upper_attr # 这会作用到这个模块中的所有类
class Foo(object):
# 我们也可以只在这里定义__metaclass__,这样就只会作用于这个类中
bar = 'bip'
Python中的一切都是对象,它们要么是类的实例,要么是元类的实例,除了type。type实际上是它自己的元类。
网友评论