【发布时间】:2018-02-13 01:45:38
【问题描述】:
我有一个相对较大的 Python 项目,为了尽量减少调试时间,我正在尝试模拟低级语言的一些方面。具体
- 能够进行类型转换(静态类型)
- 防止向类添加动态属性。
我一直在使用 mypy 来捕获类型转换错误,并且我一直在我的类实例中定义 __slots__ 以防止动态添加。
在某一时刻,我需要一个列表,其中包含两个不同的子类(它们具有相同的父类),它们的属性略有不同。 mypy 不喜欢所有列表项中都不存在的列表项的属性调用这一事实。但是,使父对象过于笼统意味着不会阻止动态添加另一个子对象中存在的变量。
为了解决这个问题,我调试/强制自己使用以下似乎可行的代码示例:
from abc import ABCMeta
from typing import List
class parentclass(metaclass=ABCMeta):
__slots__:List[str] = []
name: None
class withb(parentclass):
__slots__ = ['b','name']
def __init__(self):
self.b: int = 0
self.name: str = "john"
class withf(parentclass):
__slots__ = ['f','name']
def __init__(self):
self.name: str = 'harry'
self.f: int = 123
bar = withb()
foo = withf()
ls: List[parentclass] = [bar, foo]
ls[0].f = 12 ## Needs to fail either in Python or mypy
for i in range(1):
print(ls[i].name)
print(ls[i].b) ## This should NOT fail in mypy
这行得通。但我不确定为什么。如果我不初始化父级中的变量(即仅将它们设置为None 或int),那么它们似乎不会被带入子级。但是,如果我给他们一个占位符值,例如f:int = 0 在父母中,然后他们进入孩子,我的支票不再起作用。
谁能向像我这样的白痴解释这种行为?我想知道这样我就不会搞砸实现某些东西并引入更多错误!
顺便说一句:我确实尝试过 List[Union[withb, withf]] 但这也没有用!
【问题讨论】:
标签: python python-3.x slots mypy abc