python如何定义类_在Python中自定义类的创建方式

Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。

当人们在想要创建一个定制类的时候,他们可能通常想到的是元类和类修饰器。在通常的会话中元类一般作为创建类的开始而类修饰符作为结束。但是您可能不知道的是在类创建中还有另外的两个步骤需要调整:__prepare__()和__init_subclass__()(分别在Python3.0和3.6中添加)。

这个__prepare__()钩子用于在构造过程中指定用于类命名空间的对象(对象被复制到一个字典中最后存储到__dict__)。该方法在元类指定,并且在__call__之前调用。历史上__prepare__()方法被用来返回OrderedDict,以便类中事物的定义顺序可以在以后知道。但是由于返回的对象被用作类的命名空间,您还可以用它来注入要在类定义中使用的对象。

从David Beazley得到了一个点子,你可以滥用__prepare__()以致你可以定义一个ABC使得abstractmethod在类定义中隐含了。

0b5b2b7738734c77ac7acfd51090df47.png

使用这个元类你可以得到abstractmethod而不用通过abc来得到它。

68abbd1ccf3a4110ac644132709d7d5a.png

这种做法是因为创建类的方式本质上是通过使用类的body并将其传递给exec(),同时使用__prepare__()的结果作为区域变量。

另一种调整类创建的方式是__init_subclass__()。当定义类被子类化时,该方法被调用。它传递了提供给类定义行的子类和任何关键字参数。

为了展示一种使用这种方式的方法,我意识到你可以滥用变量类型的注释来形成一个“可怕”版本的Hynek Schlawack的attrs项目。基本上下面的类自动定义一个__init__()和(可选)__repr__()为一个基于变量类型注释的类。

026e975433954c7aa3c6560bad9d6e50.png

这样就可以创建您可能使用的简单的Python对象types.SimpleNamespace(另外:请不要滥用collections.namedtuple来生成一个简单项目;这个类意味着帮助搬运API们来返回一个元组到一个更面向对象的API,所以开始使用namedtuple意味着你最终泄露一个你可能并不想以它开始的元组API)。

e5ed212ee6c144a5bfa596ef6d826a7a.png

您也可以使用类定义的关键字参数来跳过__repr__()定义。

e1926229b6584dd2b5cf97a2d4a35adb.png

和所有调整类定义的东西一样,你一定要非常小心,不要滥用这些东西。调整怎样进行类创建可能很难调试,只有当您在有真正合法的用例的时候才能使用。但是,如果您遇到使用该代码的代码,或者您真的有需要但没有其他合理选项的时候,那么这个东西值得您了解。

Brett Cannon

Vancouver,BC,Canada英文原文:https://snarky.ca/customizing-class-creation-in-python/

译者:liuyuexiao

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值