我想输入提示继承结构,但我不知道如何正确执行。这个想法是函数 c 可以采用 A 的任何子类。一些子类具有其他子类没有的属性,并且这些属性不是在父类中定义,而是在子类中定义。函数 c 检查子类,如果它是正确的,则使用该类的特定属性。在此设置中,PyCharm 抱怨该参数不在父类中。
from abc import ABC
from typing import Type
class A(ABC):
def __init__(self, a):
self.a = a
class B(A):
def __init__(self, a):
super(B, self).__init__(a=a)
self.b = a + 1
class D(A):
def __init__(self, a):
super(D, self).__init__(a=a)
self.d = a - 1
def c(arg: Type[A]):
if type(arg) is B:
print(arg.b)
if type(arg) is D:
print(arg.d)
给出“未解析的 A 类属性引用‘b’”。有什么建议吗? 非常感谢!
令我更加好奇的是,下面的内容也抱怨 arg.a。当我在提示中使用 Type[A] 而不是 A 时。
def c(arg: Type[A]):
if type(arg) is B:
print(arg.b)
if type(arg) is D:
print(arg.d)
print(arg.a)
遇到的问题是将类型提示与实例属性混淆了。当使用
Type[A]
时,是在说该参数应该是类
A
本身或其子类,而不是
A
的实例。
以下是解决此问题的两种方法:
1. 使用 isinstance 和类型检查:
from abc import ABC
from typing import Type
class A(ABC):
def __init__(self, a):
self.a = a
class B(A):
def __init__(self, a):
super(B, self).__init__(a=a)
self.b = a + 1
class D(A):
def __init__(self, a):
super(D, self).__init__(a=a)
self.d = a - 1
def c(arg: A):
if isinstance(arg, B):
print(arg.b) # 现在可以访问 arg.b
if isinstance(arg, D):
print(arg.d) # 现在可以访问 arg.d
print(arg.a) # 可以访问 arg.a,因为它在父类 A 中定义
在这个版本中,我们将
arg: Type[A]
更改为
arg: A
,这意味着我们期望
A
的一个实例。然后,我们使用
isinstance(arg, B)
和
isinstance(arg, D)
来检查
arg
的实际类型,并在确定类型后访问相应的属性。
2. 使用类型提示和类型守卫:
from abc import ABC
from typing import Type
class A(ABC):
def __init__(self, a):
self.a = a
class B(A):
def __init__(self, a):
super(B, self).__init__(a=a)
self.b = a + 1
class D(A):
def __init__(self, a):
super(D, self).__init__(a=a)
self.d = a - 1
def c(arg: A):
if isinstance(arg, B):
print(arg.b) # 现在可以访问 arg.b
elif isinstance(arg, D):
print(arg.d) # 现在可以访问 arg.d
print(arg.a) # 可以访问 arg.a,因为它在父类 A 中定义
在这个版本中,我们使用
isinstance
检查类型,并在每个
if
语句块中创建了一个类型守卫。类型守卫告诉 MyPy 在该块中
arg
的类型是什么,从而允许我们访问正确的属性。
这两种方法都可以解决的问题,并使的代码更易于理解和维护。建议选择最适合的编码风格和项目需求的方法。
标签:python,inheritance,python-typing From: 61457513