最近在用 mypy 请问各位大佬,怎么声明一个带类型的空值啊,之后才会再对它赋值

2021-11-16 19:01:57 +08:00
 ChrisFreeMan
class GameStart(GameManager):
    def __init__(self, metadata: Dict[str, str]):
        super().__init__(metadata)
        self.bird: str = random.choice(listdir_clean(settings.BIRD_IMG_PATHS))
        self.metadata['bird'] = self.bird
        # load images
        self.bird_image: Union[surface.Surface, None] = None
        self.background_image: Union[surface.Surface, None] = None
        self.ground_image: Union[surface.Surface, None] = None
        self.start_image: Union[surface.Surface, None] = None
        self._load_content()

以上是我会先声明一些空的图片对象,之后再在 load_content 里面加载这些对象

我不能直接声明一个 Surface 类型再赋值为 None ,这样插件会报错,也无法通过 mypy 类型检查,但是赋值为 Union 类型不仅每次要判断非 None ,在一些场景下还会出现类型不兼容,请问有没有更优雅的方法

1740 次点击
所在节点    Python
9 条回复
Kilerd
2021-11-16 19:09:49 +08:00
Optional ?
Trim21
2021-11-16 19:11:25 +08:00
@Kilerd #1 Optional[T]和 Union[T, None]是等价的
ChrisFreeMan
2021-11-16 19:12:33 +08:00
@Kilerd 试了下不行,如果接受对方声明是 Surface 类型,Optional 和 Union 都会报错
Kilerd
2021-11-16 19:21:57 +08:00
把参数定义到类上 ,不写等于那一截

bird_image: surface.Surface

这样好像就行,看看这里 https://stackoverflow.com/questions/60925137/using-mypy-with-with-lazy-initialization-of-instance-attributes
ChrisFreeMan
2021-11-16 19:28:20 +08:00
@Kilerd 好,如果没有更好的方法这个方法我先顶上,多谢。之前其实也有想过这个方法,但又感觉这是一个取巧的方法,毕竟我没有真正声明它,因为它的动态特性
ClericPy
2021-11-16 21:38:49 +08:00
在用

"python.linting.mypyArgs": [
"--ignore-missing-imports",
"--follow-imports=silent",
"--show-column-numbers",
"--no-strict-optional"
],
abersheeran
2021-11-17 10:48:00 +08:00
https://github.com/abersheeran/baize/blob/master/baize/datastructures.py#L364

其实把你 = 右边的都去掉就行了。你可以理解为声明了一个变量。初始化并不一定是需要马上做的,可以后面初始化。
ChrisFreeMan
2021-11-17 11:02:41 +08:00
@abersheeran 好,我先用一段时间看看会不会有什么坑
2i2Re2PLMaDnghL
2021-11-17 13:13:38 +08:00
你 _load_content 是否存在逻辑上的可能不为这几个赋值?
如果可能,那么显然你的类型确实就是 Optional[Surface],每次传出时确实应当进行 None 的检验
如果不可能,那么显然你不应该先赋 None ,直接在 class 定义里 bird_image: surface.Surface 就行
_load_content 被视为 __init__ 过程的一部分。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/815855

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX