python 元类

python 元类

时间: 2021-2-1 , python==3.7

Python中实例对象时由类对象实例化的,而类对象是由元类实例化的。

一、 重新认识type

1.1 所有的类对象都是基于type类来创建的

a = 100
type(a)
type(type(a))
type
d = {"test": "cdefg"}
print(type(d))
print(type(type(d)))
<class 'dict'>
<class 'type'>
class Dog(object):
    name = "旺财"
d_ = Dog()
print(type(Dog))
<class 'type'>
print(type(d_))
print(type(type(d_)))
<class '__main__.Dog'>
<class 'type'>

可以看到,当使用了多次type函数时, 所有的结果最终都等于 class type.

1.2使用type动态的创建一个类对象

# type 第一个参数字符串,类名Dog, 第二个参数元组,继承object,第三个参数字典,定义类的属性、方法
D = type("Dog", (object,), {"name": "旺财", "say": lambda self: print("旺!旺!")})
dog = D()
print(dog.name)
dog.say()
旺财
旺!旺!
type(dog)
__main__.Dog

在这里可以看到,type可以创建一个类对象, 也就是说type是一个元类

二、 元类

type是一个元类,默认元类都是使用type, 除非指定 metaclass

2.1 自定义一个原类

# 重写new方法, new方法是用来实例化一个类对象的
class FishType(type):
    def __new__(mcs, name, bases, attrs):
        if not (attrs.get("eat") and attrs.get("swim")):
            # 规定Fish必须拥有 eat 与 swim, 否则抛出异常
            raise Exception("鱼必必须拥有eat与swim两个方法")
        # 调用父类即,type的 __new__ 创建一个类对象
        return super().__new__(mcs, name, bases, attrs)
    
    def __setattr__(cls, name, value):
        raise Exception("不允许修改类属性")
# class Fish(object, metaclass=FishType):
#     pass
# 直接class定义Fish抛出异常
class Fish(object, metaclass=FishType):
    
    name = "fish"
    def eat():
        print("eating")
    def swim():
        print("swimming")
f = Fish()
f.swim
print(f)
print(type(f))
print(type(type(f)))
print(type(type(type(f))))
<__main__.Fish object at 0x0000018D55FB1288>
<class '__main__.Fish'>
<class '__main__.FishType'>
<class 'type'>
try:
    print("原来的name: ", Fish.name)
    # 试图修改类对象的属性
    Fish.name = "咸鱼"
    print(Fish.name)
except Exception as e:
    print(e)
原来的name:  fish
不允许修改类属性

2.2 class 魔法属性

# __class__ 等于type的值
fish = Fish()
print(fish.__class__)
print(fish.__class__.__class__)
print(fish.__class__.__class__.__class__)
print(fish.__class__ is type(fish))
<class '__main__.Fish'>
<class '__main__.FishType'>
<class 'type'>
True
a = 100
print(a.__class__)
d = {}
print(d.__class__)
print(a.__class__ is type(a))
print(d.__class__ is type(d))
<class 'int'>
<class 'dict'>
True
True

三、总结

  • 元类用于创造类对象。
  • type是默认的元类, type可以用于动态创建一个类对象。
  • 自定义元类,继承type,重写 new 方法。 用途: 实现对类对象一些属性的限制,或者修改、规范类的定义, 比如类对象属性必须全部大写、禁止修改类对象值、必须拥有某些属性等等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值