零基础入门python3.7 ——基础知识总结(二十五)type()动态创建类和MetaClass元类

type()这个内置函数不仅可以检查数据类型。还可以创建一个类,

一。type()函数的用法

  • 检查数据类型
a = 1000
print(type(a))

b = 'python'
print(type(b))

<class 'int'>
<class 'str'>
  • 创建类。可以接受三个参数。第一个参数表示要创建的类名。第二个参数是一个元祖用于储存要创建类的父类。 第三个参数为字典 储存类内定义的属性和方法。
class Person:
    name = "jack"
    city = "成都"

person = type("Person1", (Person,), {"name": "alice", "age": 3})

print(person.name)
print(person.age)
print(person.city)

alice
3
成都
  • type()在创建类时函数的三个参数是必要的。 否则会抛出异常
class Person:
    name = "jack"
    city = "成都"

person = type("Person1", {"name": "alice", "age": 3})

print(person.name)
print(person.age)
print(person.city)

Traceback (most recent call last):
  File "/Users/apple/Documents/重要文件/python3/python21.py", line 5, in <module>
    person = type("Person1", {"name": "alice", "age": 3})
TypeError: type() takes 1 or 3 arguments
  • 父类只有一个元素的首个元素后必须加逗号。否则会抛出异常
class Person:
    name = "jack"
    city = "成都"

person = type("Person1", (Person ),{"name": "alice", "age": 3})

print(person.name)
print(person.age)
print(person.city)

Traceback (most recent call last):
  File "/Users/apple/Documents/重要文件/python3/python21.py", line 5, in <module>
    person = type("Person1", (Person ),{"name": "alice", "age": 3})
TypeError: type.__new__() argument 2 must be tuple, not type
  • 所有类默认继承的是object
person = type("Person1", (object,),{"name": "alice", "age": 3})

print(person.name)
print(person.age)

alice
3

二。MetaClass元类

元类本身就是一个类。但是相对于普通类而言可以动态的修改类属性和类方法。为了使元类使用起来方便一般是先创建元类。然后在用元类去创建类,最后在实例化,要想把一个类设计成元类是有条件的。

  • 必须显示的继承自type类 
  • 类中补虚要实现且定义__new__()方法。而且该方法必须要返回一个该类的实例对象。原因在于在使用元类创建类时。该__new__()方法会自动执行。用于修改新的类。

__new__()方法同时还自带四个参数

  • cls表示动态修改的类
  • name表示动态修改的类名
  • bases表示被动态修改的类的所有父类
  • attrs表示被动态修改的类的所有属性和方法组成的字典
class Person(type):
    def __new__(cls, name, bases, attrs):
        attrs["name"] = "小王"
        attrs["getName"] = lambda self: self.name
        return  super().__new__(cls, name, bases, attrs)
  • 因为元类的__new__()中手动添加了新的属性和方法那么也就意味着通过元类创建的类会添加额外的属性和方法
class Person(type):
    def __new__(cls, name, bases, attrs):
        attrs["name"] = "小王"
        attrs["getName"] = lambda self: self.name
        return  super().__new__(cls, name, bases, attrs)

class Person1(object, metaclass=Person):
    pass

a = Person1()
print(a.name)
print(a.getName())

小王
小王
  • 不难发现元类不单单可以创建一个类。是可以创建多个类的
class Person(type):
    def __new__(cls, name, bases, attrs):
        attrs["name"] = "小王"
        attrs["getName"] = lambda self: self.name
        return  super().__new__(cls, name, bases, attrs)

class Person1(object, metaclass=Person):
    pass

class Person2(object,metaclass= Person):
    pass

a = Person1()
print(a.name)
print(a.getName())

b = Person2()
print(b.name)
print(b.getName())

小王
小王
小王
小王
  • 在通过元类创建类时必须通过metaclass=“类名”指定元类
class Person(type):
    def __new__(cls, name, bases, attrs):
        attrs["name"] = "小王"
        attrs["getName"] = lambda self: self.name
        return  super().__new__(cls, name, bases, attrs)

class Person2(metaclass= Person):
    pass

b = Person2()
print(b.name)
print(b.getName())

小王
小王

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值