python总结(十二):type(),动态创建类,使用元类

一、定义常量

1.当我们需要定义常量时,一个办法是用大写变量通过整数来定义,好处是简单,缺点是类型是int,并且仍然是变量。

2.使用枚举类

from enum import Enum
Month = Enum('onth', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
for name, member in Month.__members__.items():
    print(name,member, member.value)
print(Month["Jan"])
print(Month.Jan)
print(Month(1))
print(Month["Jan"].value)
print(Month.Jan.value)
print(Month(1).value)

    运行结果: 

E:\soft\python3\python.exe C:/Users/Lenovo/PycharmProjects/matplot_graph/venv/classtext.py
Jan onth.Jan 1
Feb onth.Feb 2
Mar onth.Mar 3
Apr onth.Apr 4
May onth.May 5
Jun onth.Jun 6
Jul onth.Jul 7
Aug onth.Aug 8
Sep onth.Sep 9
Oct onth.Oct 10
Nov onth.Nov 11
Dec onth.Dec 12
onth.Jan
onth.Jan
onth.Jan
1
1
1

二、动态创建类——type()

1.定义:

要创建一个class对象,type()函数依次传入3个参数:

  1. class的名称;
  2. 继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
  3. class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上。

      通过type()函数创建的类和直接写class是完全一样的,因为Python解释器遇到class定义时,仅仅是扫描一下class定义的语法,然后调用type()函数创建出class。正常情况下,我们都用class Xxx...来定义类,但是,type()函数也允许我们动态创建出类来,也就是说,动态语言本身支持运行期动态创建类,这和静态语言有非常大的不同,要在静态语言运行期创建类,必须构造源代码字符串再调用编译器,或者借助一些工具生成字节码实现,本质上都是动态编译,会非常复杂。

2. 例子:

>>> def fn(self, name='world'): # 先定义函数
...     print('Hello, %s.' % name)
...
>>> Hello = type('Hello', (object,), dict(hello=fn)) # 创建Hello class
>>> h = Hello()
>>> h.hello()
Hello, world.
>>> print(type(Hello))
"""类类型是type"""
<class 'type'>
>>> print(type(h))
"""实例类型是类名字"""
<class '__main__.Hello'>

三、元类:

1.__new__():

new函数并不是定义在object中,它定义在 元类 type里面,可以通过查看 help(type) 或者是help(type.__new__)进行查看,__new__是type的成员,而python中所有的类都是type的实例,包括object,故而通过object,Student.__new__()的形式初始化就在正常不过了,这不就是“ 实例.方法 ”吗

def __new__(cls,*args,**kwargs):
        print('我是new函数!')   #这是为了追踪new的执行过程
        print(type(cls))        #这是为了追踪new的执行过程
        return object.__new__(cls)  #调用父类的(object)的new方法,返回一个Student实例,
                                     #这个实例传递给init的self参数
"""
因为这不就是和定义一样吗?虽然多了一个cls,
实际上因为是*args的关系,这并不会有影响,这个参数实际上就是要创建的那个类的实例所属的类型,
如Student。
"""
"""
__new__()方法负责创建实例,而__init__()仅仅是负责实例属性相关的初始化而已,执行顺序是,先new后init。
"""

(1)__new__方法是定义在元类type里面的,作用就是专门创建实例的。(2)__new__的本质上是一个“类方法”,故而第一个参数为cls,但是因为系统知道它是类方法,所以有不需要显式添加@classmethod(3)__new__必须具有返回值,否则无法创建对象,因为__init__函数需要这个返回值(4)自己在定义__new__的时候,参数要与__init__函数的参数匹配,我可以不用到这些参数,但一定要匹配。或者可以使用*arg和**args的形式。

class Parent:
    def __new__(cls,*arg):   #这里是正确的,因为*arg可以匹配任意多个未知参数
        return object.__new__(cls)
    def __init__(self,age,name):
        self.age=age
        self.name=name
p=Parent(23,'feifei')
print(p.age)
print(p.name)

 2.__class__():

实例调用__class__属性时会指向该实例对应的类,然后可以再去调用其它类属性.首先用__class__将self实例变量指向类,然后再去调用__name__类属性,通常情况__name__的值为‘__main__’.__class__功能和type()函数一样,都是查看对象所在的类。

class Student(object):
    def __init__(self,name):
        self.name = name
stu = Student("tom")
print(type(stu),type(Student))
print(stu.__class__, Student.__class__, stu.__class__.__class__)

"""以下是运行结果"""
#<class '__main__.Student'> <class 'type'>
#<class '__main__.Student'> <class 'type'> <class 'type'>

3.super()函数:调用父类

class A:
     def add(self, x):
         y = x+1
         print(y)
class B(A):
    def add(self, x):
        super().add(x)

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值