Gle*_*ord 31 python inheritance
这个问题建立在许多假设之上.如果一个假设是错误的,那么整个事情就会失败.我还是相对较新的Python,刚刚进入了好奇/探索阶段.
我的理解是Python不支持创建不能被子类化的类(最终类).但是,在我看来,Python 中的bool类不能被子类化.当考虑bool类的意图时,这是有道理的(因为bool只应该有两个值:true和false),我很满意.我想知道的是这个课程是如何被标记为最终的.
所以我的问题是: Guido如何设法阻止bool的子类化?
>>> class TestClass(bool):
pass
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
class TestClass(bool):
TypeError: type 'bool' is not an acceptable base type
Run Code Online (Sandbox Code Playgroud)
相关问题: 为什么我不能在Python中扩展bool?
Dun*_*can 47
您可以非常轻松地模拟Python 3.x中的相同效果:
class Final(type):
def __new__(cls, name, bases, classdict):
for b in bases:
if isinstance(b, Final):
raise TypeError("type '{0}' is not an acceptable base type".format(b.__name__))
return type.__new__(cls, name, bases, dict(classdict))
class C(metaclass=Final): pass
class D(C): pass
Run Code Online (Sandbox Code Playgroud)
将给出以下输出:
Traceback (most recent call last):
File "C:\Temp\final.py", line 10, in <module>
class D(C): pass
File "C:\Temp\final.py", line 5, in __new__
raise TypeError("type '{0}' is not an acceptable base type".format(b.__name__))
TypeError: type 'C' is not an acceptable base type
Run Code Online (Sandbox Code Playgroud)
ken*_*ytm 13
您只能通过C API执行此操作.清除Py_TPFLAGS_BASETYPE的位tp_flags的类型的对象.
像这样:http://svn.python.org/projects/python/trunk/Objects/boolobject.c(vs intobject.c where where Py_TPFLAGS_BASETYPEset).
在 Python 3.6 中,你应该阻止子类化而不使用像这样的元类:
class SomeBase:
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
if cls is not SomeBase:
raise TypeError("SomeBase does not support polymorphism. Use composition over inheritance.")
class Derived(SomeBase):
pass
Run Code Online (Sandbox Code Playgroud)
在 Python 3.8 中,您还应该使用final装饰器来引发类型检查错误:
from typing import final
@final
class SomeBase:
...
Run Code Online (Sandbox Code Playgroud)
类型检查由 MyPy 之类的程序完成,它们是可选的。
Final和@final类型现在可以在typing_extensions.
我写了一篇文章,涵盖了这种新类型的几乎所有部分:https://sobolevn.me/2018/07/real-python-contants
一些类的例子:
from typing_extensions import final
@final
class HRBusinessUnit(AbstractBusinessUnit):
def grant_permissions(self) -> None:
self.api.do_some_hr_stuff()
class SubHRBusinessUnit(HRBusinessUnit): # mypy will raise an error
def grant_permissions(self) -> None:
self.api.do_some_it_stuff()
Run Code Online (Sandbox Code Playgroud)
并带有常数:
from typing_extensions import Final
DAYS_IN_A_WEEK: Final = 7
DAYS_IN_A_WEEK = 8 # mypy will raise an error
Run Code Online (Sandbox Code Playgroud)
我们还有一个小库来编写final也在运行时检查的类!https://github.com/wemake-services/final-class
from final_class import final
@final
class Example(object): # You won't be able to subclass it!
...
class Error(Example): # Raises `TypeError`
...
Run Code Online (Sandbox Code Playgroud)
特征:
| 归档时间: |
|
| 查看次数: |
2249 次 |
| 最近记录: |