首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python中的元类到底是啥?一文讲透

每次看到Python元类相关的讨论,脑袋就嗡嗡的。这玩意儿看着高大上,用的时候又糊里糊涂。其实元类就是个创建类的模板,说白了就是类的类。听着绕口?别急,一点点来捋这事儿。

类也是对象?没毛病!

Python里啥都是对象,类也不例外:

class Dog:

def bark(self):

print("汪汪汪!")

# 类也能当变量用

animal = Dog

pet = animal() # 和 Dog() 一个意思

pet.bark() # 输出:汪汪汪!

温馨提示:类对象和类的实例是两码事,弄混了就要踩坑。

type不光能查类型,还能造类

平时都拿type查类型,其实它还有个绝活:

# 普通的类定义

class Cat:

def meow(self):

print("喵喵喵~")

# type创建的类,一样能用

Dog = type('Dog', (), {'bark': lambda self: print("汪汪汪!")})

kitty = Cat()

doggy = Dog()

kitty.meow() # 输出:喵喵喵~

doggy.bark() # 输出:汪汪汪!

看明白了不?type接受三个参数:类名、父类元组(为空就是没有父类)、属性字典。

元类就是个类工厂

元类说白了就是个类生产车间,能批量产出各种类:

class AnimalMeta(type):

def __new__(cls, name, bases, attrs):

# 给所有动物类加个叫声

attrs['make_sound'] = lambda self: print(f"我是{name}, 我会叫!")

return super().__new__(cls, name, bases, attrs)

# 用元类造类

class Dog(metaclass=AnimalMeta):

pass

class Cat(metaclass=AnimalMeta):

pass

dog = Dog()

cat = Cat()

dog.make_sound() # 输出:我是Dog, 我会叫!

cat.make_sound() # 输出:我是Cat, 我会叫!

温馨提示:__new__方法比__init__还要早,它负责创建类对象,而__init__只是初始化。

元类能干啥用?

光说不练假把式,来点实在的:

class ValidatorMeta(type):

def __new__(cls, name, bases, attrs):

# 检查所有方法名是否符合规范

for key, value in attrs.items():

if callable(value) and not key.startswith('_'):

if not key.islower():

raise NameError(f'方法名{key}必须全小写!')

return super().__new__(cls, name, bases, attrs)

class MyClass(metaclass=ValidatorMeta):

def good_method(self): # 这个方法名没问题

pass

def BadMethod(self): # 这个方法名会报错

pass

瞧见没?元类能在类创建时就把不规范的代码揪出来,省得上线了再改。

继承也能玩出花

元类还能跟继承组合在一起耍:

class Base(metaclass=ValidatorMeta):

pass

class Child(Base): # 继承了Base,也会被ValidatorMeta检查

def GoodMethod(self): # 照样会报错

pass

温馨提示:Python3中,元类是可以继承的,不过继承链有点复杂,用的时候多查查文档。

元类就像个严格的保姆,替你看着类的一举一动。不过也别滥用,普通的开发基本用不着,除非你想写个框架或者搞点黑魔法。写代码图省事,但该严格的地方还得严格,不然等出了问题再找bug那才叫闹心呢。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OC-HvB_tfvQemXkBXs3LFrMw0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券