我们来看下面的代码:
import typing
def make_getter(field: str) -> typing.Callable[['A'], int]:
def getter(self: 'A') -> int:
return int(self.dict[field])
return getter
def make_setter(field: str) -> typing.Callable[['A', int], None]:
def setter(self: 'A', value: int):
self.dict[field] = str(value)
return setter
class A:
def __init__(self, d: dict):
super().__init__()
self.dict = d
get_x = make_getter('foo')
set_x = make_setter('foo')
x = property(get_x, set_x)
def get_y(self) -> int:
return int(self.dict['bar'])
def set_y(self, value: int):
self.dict['bar'] = str(value)
y = property(get_y, set_y)
我定义了2个属性:
x
和
y
两者都应该工作正常,没有任何问题,两者应该具有相同的行为。
接下来,以下代码:
a = A(dict())
a.x = 10
print(a.x)
a.y = 20
print(a.y)
PyCharm 编辑器显示:
“属性无法读取”
on
a.x
但这段代码执行得很好,没有任何问题。
第一个想法是 PyCharm 错误地推断了类型。 但是看看我录制的这个短视频。 我看不出类型有任何问题。|| |另外:
它的输出:
print(repr(a.get_x), repr(a.get_y))
print(repr(A.get_x), repr(A.get_y))
print(repr(A.x), repr(A.y))
...所以
<bound method make_getter.<locals>.getter of <__main__.A object at 0x7f7d25145f28>> <bound method A.get_y of <__main__.A object at 0x7f7d25145f28>>
<function make_getter.<locals>.getter at 0x7f7d25132e18> <function A.get_y at 0x7f7d25132f28>
<property object at 0x7f7d25143c78> <property object at 0x7f7d25143cc8>
和
x
几乎等效。
y
为什么 PyCharm 这么说?
我做错了什么或者这是一种错误?如何修复它(不禁用此类警告)? I did something wrong or it's kind of bug? How to fix it (w/o disabling this type of warning)?
这是一个 PyCharm 已知问题,与它处理通过
@property
装饰器或内置
property()
函数创建的属性的方式有关,尤其是在涉及类型提示时。尽管代码在运行时可以正常工作,但 PyCharm 的静态分析器有时无法正确推断类型,从而导致误报“无法读取属性”警告。
以下是一些可能的解决方法:
1. 忽略该警告:
- 最简单(但不太令人满意)的解决方法是在该特定行上禁用该警告。可以将鼠标悬停在警告上,然后单击出现的灯泡图标,然后选择“忽略此类问题”。
2. 添加类型提示到
property
对象:
-
可以通过在类级别为
property
对象添加类型提示来帮助 PyCharm 更好地理解类型。
python
class A:
...
x: int = property(make_getter('foo'), make_setter('foo'))
y: int = property(get_y, set_y)
3. 使用
@property
装饰器:
-
尽管你的代码在功能上是正确的,但使用
@property
装饰器通常更清晰,并且可以提高 PyCharm 对类型的推断能力。
```python class A: ...
@property
def x(self) -> int:
return int(self.dict['foo'])
@x.setter
def x(self, value: int):
self.dict['foo'] = str(value)
...
```
4. 更新 PyCharm:
- 这个问题可能在 PyCharm 的新版本中已经得到解决。尝试更新到最新版本,看看是否解决了该问题。
如果这些方法都不起作用,可以考虑向 JetBrains 提交错误报告,提供重现该问题的最小示例。
标签:python,pycharm,python-typing From: 43039167