元类1. 类也是对象在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段 。在Python中这一点仍然成立:
>>> class ObjectCreator(object):… pass…>>> my_object = ObjectCreator()>>> print(my_object)<__main__.ObjectCreator object at 0x8974f2c>但是,Python中的类还远不止如此 。类同样也是一种对象 。是的,没错,就是对象 。只要你使用关键字class,Python解释器在执行的时候就会创建一个对象 。
下面的代码段:
>>> class ObjectCreator(object):… pass…将在内存中创建一个对象,名字就是ObjectCreator 。这个对象(类对象ObjectCreator)拥有创建对象(实例对象)的能力 。但是,它的本质仍然是一个对象,于是乎你可以对它做如下的操作:
你可以将它赋值给一个变量
你可以拷贝它
你可以为它增加属性
你可以将它作为函数参数进行传递
下面是示例:
>>> print(ObjectCreator) # 你可以打印一个类,因为它其实也是一个对象<class '__main__.ObjectCreator'>>>> def echo(o):… print(o)…>>> echo(ObjectCreator) # 你可以将类做为参数传给函数<class '__main__.ObjectCreator'>>>> print(hasattr(ObjectCreator, 'new_attribute'))Fasle>>> ObjectCreator.new_attribute = 'foo' # 你可以为类增加属性>>> print(hasattr(ObjectCreator, 'new_attribute'))True>>> print(ObjectCreator.new_attribute)foo>>> ObjectCreatorMirror = ObjectCreator # 你可以将类赋值给一个变量>>> print(ObjectCreatorMirror())<__main__.ObjectCreator object at 0x8997b4c>2. 动态地创建类因为类也是对象,你可以在运行时动态的创建它们,就像其他任何对象一样 。首先,你可以在函数中创建类,使用class关键字即可 。
>>> 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解释器自动创建这个对象 。但就和Python中的大多数事情一样,Python仍然提供给你手动处理的方法 。
还记得内建函数type吗?这个古老但强大的函数能够让你知道一个对象的类型是什么,就像这样:
>>> print(type(1)) # 数值的类型<type 'int'>>>> print(type("1")) # 字符串的类型<type 'str'>>>> print(type(ObjectCreator())) # 实例对象的类型<class '__main__.ObjectCreator'>>>> print(type(ObjectCreator)) # 类的类型<type 'type'>仔细观察上面的运行结果,发现使用type对ObjectCreator查看类型是,答案为type,是不是有些惊讶 。。。看下面
3. 使用type创建类type还有一种完全不同的功能,动态的创建类 。
type可以接受一个类的描述作为参数,然后返回一个类 。(要知道,根据传入参数的不同,同一个函数拥有两种完全不同的用法是一件很傻的事情,但这在Python中是为了保持向后兼容性)
type可以像这样工作:
type(类名, 由父类名称组成的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
比如下面的代码:
In [2]: class Test: #定义了一个Test类 ...: pass ...:In [3]: Test() # 创建了一个Test类的实例对象Out[3]: <__main__.Test at 0x10d3f8438>可以手动像这样创建:
Test2 = type("Test2", (), {}) # 定了一个Test2类In [5]: Test2() # 创建了一个Test2类的实例对象Out[5]: <__main__.Test2 at 0x10d406b38>我们使用"Test2"作为类名,并且也可以把它当做一个变量来作为类的引用 。类和变量是不同的,这里没有任何理由把事情弄的复杂 。即type函数中第1个实参,也可以叫做其他的名字,这个名字表示类的名字
In [23]: MyDogClass = type('MyDog', (), {})In [24]: print(MyDogClass)<class '__main__.MyDog'>使用help来测试这2个类
In [10]: help(Test) # 用help查看Test类Help on class Test in module __main__:class Test(builtins.object) | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined)In [8]: help(Test2) #用help查看Test2类Help on class Test2 in module __main__:class Test2(builtins.object) | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined)
推荐阅读
- CSS块元素、内联元素、内联块元素
- CSS美化单选框 radio 、多选框 checkbox 和 switch开关按钮
- 如何查看Oracle数据库物理读、逻辑读前10的sql?
- Python数据可视化的四种简易方法
- 阿里P8架构师谈:MySQL数据库的索引原理、与慢SQL优化的5大原则
- Python测试工具 | 8 个很棒的pytest插件
- 男人有这点至少精神出轨了
- 中国男人最想要的妻子
- 男人最怕女人说三个字,是什么?
- 科普真相!西瓜、冰棍、绿豆汤真是消暑神器?