码迷,mamicode.com
首页 > 编程语言 > 详细

【python进阶】详解元类及其应用1

时间:2018-04-18 23:35:28      阅读:246      评论:0      收藏:0      [点我收藏+]

标签:pass   ble   ict   针对   操作   继承   添加   对象   pre   

前言

元类在python中是很重要的一部分,我将分两次去讲解元类及其应用,此篇为详解元类及其应用第一篇,下面开始今天的说明~~~

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)拥有创建对象(实例对象)的能?。但是,它的本质仍然是 ?个对象,于是乎你可以对它做如下的操作:
1. 你可以将它赋值给?个变量

2. 你可以拷?它

3. 你可以为它增加属性

4. 你可以将它作为函数参数进?传递

下?是示例:

>>>    print(ObjectCreator)#你可以打印?个类,因为它其实也是?个对象 
<class    __main__.ObjectCreator> 
>>>    def    echo(o):
...        print(o)
... 
>>>    echo(ObjectCreator)#你可以将类做为参数传给函数 
<class    __main__.ObjectCreator> 
>>>    print(hasattr(ObjectCreator,new_attribute))
False 
>>>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__.choose_class.<locals>.Foo>
>>> print(MyClass())#你可以通过这个类创建类实例,也就是对象
<__main__.choose_class.<locals>.Foo object at 0x000001C54F7007B8>

但这还不够动态,因为你仍然需要??编写整个类的代码。由于类也是对 象,所以它们必须是通过什么东?来?成的才对。当你使?class关键字时, Python解释器?动创建这个对象。但就和Python中的?多数事情?样, Python仍然提供给你?动处理的?法。
还记得内建函数type吗?这个古?但强?的函数能够让你知道?个对象的类 型是什么,就像这样:

>>> print(type(1))#数值的类型
<class int>
>>> print(type("1"))#字符串的类型
<class str>
>>> print(type(ObjectCreator()))#实例对象的类型
<class __main__.ObjectCreator> 
>>>    print(type(ObjectCreator))#类的类型 
<type type>

仔细观察上?的运?结果,发现使?type对ObjectCreator查看类型是,答案 为type, 是不是有些惊讶。。。看下?

3. 使?type创建类

type还有?种完全不同的功能,动态的创建类。
type可以接受?个类的描述作为参数,然后返回?个类。(要知道,根据传入参数的不同,同?个函数拥有两种完全不同的?法是?件很傻的事情,但 这在Python中是为了保持向后兼容性)
type可以像这样?作:
type(类名, 由?类名称组成的元组(针对继承的情况,可以为空),包含属 性的字典(名称和值))
?如下?的代码:

In [7]: class Test:#定义了?个Test类
   ...:     pass
   ...:

In [8]: Test()#创建了?个Test类的实例对象
Out[8]: <__main__.Test at 0x1c54f648518>

可以?动像这样创建:

In [9]: Test2 = type("Test2",(),{})#定义了?个Test2类

In [10]: Test2()#创建了?个Test2类的实例对象
Out[10]: <__main__.Test2 at 0x1c54f66ed68>

我们使?"Test2"作为类名,并且也可以把它当做?个变量来作为类的引?。 类和变量是不同的,这?没有任何理由把事情弄的复杂。即type函数中第1个实参,也可以叫做其他的名字,这个名字表示类的名字

In [11]: MyDogClass = type(MyDog,(),{})

In [12]: print(MyDogClass)
<class __main__.MyDog>

使?help来测试这2个类

In [13]: 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 [14]: 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)

4.使?type创建带有属性的类

type 接受?个字典来为类定义属性,因此

In [15]: Foo = type(Foo,(),{bar:True})

可以翻译为:

In [16]: class Foo(object):
    ...:     bar = True

并且可以将Foo当成?个普通的类?样使?:

In [17]: print(Foo)
<class __main__.Foo>

In [18]: print(Foo.bar)
True

In [19]: f = Foo()

In [20]: print(f)
<__main__.Foo object at 0x000001C54F6511D0>

In [21]: print(f.bar)
True

当然,你可以向这个类继承,所以,如下的代码:

In [22]: class FooChild(Foo):
    ...:     pass

就可以写成:

In [23]: FooChild = type(FooChild,(Foo,),{})

In [24]: print(FooChild)
<class __main__.FooChild>

In [25]: print(FooChild.bar)
True

注意:

  • type的第2个参数,元组中是?类的名字,?不是字符串 
  • 添加的属性是类属性,并不是实例属性

【python进阶】详解元类及其应用1

标签:pass   ble   ict   针对   操作   继承   添加   对象   pre   

原文地址:https://www.cnblogs.com/ECJTUACM-873284962/p/8877973.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!