python - 动态定义的实例属性应该如何与类型提示/linting 一起使用?
问题描述
考虑下面的代码,我的类Child
继承自Parent
(一个来自第三方包的类,我无法控制)。Parent
有一个内置方法set_attributes
,用于向实例添加任意属性:
# third-party code, I can't modify this
class Parent:
def __init__(self, a: str) -> None:
self.a = a
def set_attributes(self, **kwargs) -> None:
for k, v in kwargs.items():
setattr(self, k, v)
# my code, I can modify this
class Child(Parent):
def __init__(self, a: str, b: int, c: float) -> None:
super().__init__(a=a)
self.set_attributes(b=b, c=c)
def show_attributes(self):
print(self.a)
print(self.b)
print(self.c)
这很好用,但是任何 linter 都会在该show_attributes
方法上给我一个警告,告诉我self.b
并且self.c
不存在(因为它们是在运行时定义的,当self.set_attributes(b=b, c=c)
执行该行时)。
克服此限制的一种方法是为 中的属性定义一个占位符Child.__init__
:
from typing import Optional
class Child(Parent):
def __init__(self, a: str, b: int, c: float) -> None:
super().__init__(a=a)
self.b: Optional[int] = None
self.c: Optional[float] = None
self.set_attributes(b=b, c=c)
...但现在的问题是,它self.b
不self.c
应该是真正的价值观None
——它只是一个占位符。我不希望我的 linter 考虑这些值可能None
适用于我的其余代码的可能性,因为它们不应该是。
我考虑过的其他选择是:
- 从类型提示中删除
Optional
- 现在 linter 警告我,self.b
不self.c
应该是None
:
class Child(Parent):
def __init__(self, a: str, b: int, c: float) -> None:
super().__init__(a=a)
self.b: int = None
self.c: float = None
self.set_attributes(b=b, c=c)
- 使用正确类型的默认值:这可行,但感觉很笨拙和冗长(我觉得这稍后会咬我):
class Child(Parent):
def __init__(self, a: str, b: int, c: float) -> None:
super().__init__(a=a)
self.b: int = 0
self.c: float = 0.0
self.set_attributes(b=b, c=c)
- type 提示属性,但不要给它们一个占位符值:这看起来不错,但 linter 仍然认为这些属性不存在,即使在执行该
set_attributes
方法之后:
class Child(Parent):
def __init__(self, a: str, b: int, c: float) -> None:
super().__init__(a=a)
self.b: int
self.c: float
self.set_attributes(b=b, c=c)
这些解决方案都没有让我非常满意。set_attributes
此外,如果我决定通过添加**kwargs
来保持灵活性,这些解决方案都不起作用Child.__init__
,即:
class Child(Parent):
def __init__(self, a: str, b: int, c: float, **kwargs) -> None:
super().__init__(a=a)
self.b: int
self.c: float
self.set_attributes(b=b, c=c, **kwargs)
有没有更好的方法来解决这个问题,或者这只是我必须习惯的限制?
解决方案
推荐阅读
- sql-server - 无法在 SQL Server 2017 中以 STANDBY 模式还原事务日志
- c++ - 获得最大的 Pair Wise 产品 C++ 并且输出并不总是与我的代码正确
- activemq - MassTransit - 启动总线时 AmazonMQ 的套接字异常
- r - 使用不断变化的 shapefile(只有 4 个不同的 shapefile)制作动画地图挂起
- javascript - 通过单击关闭 JS 关闭弹出窗口
- python - Discord.py 向特定频道发送消息
- python - 狮身人面像:modules.rst:警告:文档不包含在任何目录树中
- node.js - 内置中间件功能
- r - 并行运行 R 函数 / 使用 furr / 语法
- yaml - jekyll 博客新行(最小错误)