pycharm 如何处理可选None变量Python3的类型检查?

inn6fuwd  于 2022-11-08  发布在  PyCharm
关注(0)|答案(2)|浏览(206)

在下面的示例中,MyClass的init方法定义了属性self._user,该属性可以选择UserInput类型,并初始化为None。实际的用户输入应由方法set_user提供。由于某些实际原因,用户输入不能提供给方法__init__。在提供用户输入后,可以调用其他方法x1M5N1x和x1M6N1x。
向专业Python程序员提问:我真的需要在每个使用self._user的方法中添加assert ... not None吗?否则,VS Code Pylance类型检查将报告self._user可能是None。但是,我在PyCharm中尝试了相同的代码及其内置的类型检查。在那里没有出现这个问题。
作为专业的Python程序员,您更喜欢VS Code中的Pylance类型检查,还是PyCharm中的内置类型检查?
先谢谢你。

class UserInput:
    name: str
    age: int

class MyClass:
    def __init__(self):
        self._user: UserInput | None = None

    def set_user(self, user: UserInput):  # This method should be called before calling any methods.
        self._user = user

    def method_1(self):
        assert self._user is not None  # do I actually need it
        # do something using self._user, for example return its age.
        return self._user.age  # Will get warning without the assert above.

    def method_2(self):
        assert self._user is not None  # do I actually need it
        # do something using self._user, for example return its name.
bvn4nwqk

bvn4nwqk1#

我认为保留assert是最安全和最简洁的。毕竟,这取决于类的用户调用示例方法的顺序。因此,您不能保证self._user不是None

9rnv2umw

9rnv2umw2#

我认为在生产代码中使用assert是一种不好的做法。当出现问题时,您会得到大量的AssertionError,但您没有任何上下文来说明为什么要做出这种Assert。
如果set_user()应该被更早地调用,我会很想把用户放在__init__方法中,但是同样的原则也适用。

@dataclass
class UserInput:
    name: str
    age: int

class NoUserException(TypeError):
    pass

class MyClass:
    # Or this could be in the __init__ method
    def set_user(self, user: UserInput | None):
        if not user:
            raise NoUserException()
        self._user: user

    def method_1(self):
        # do something using self._user, for example return its age.
        return self._user.age

    def method_2(self):
        # do something using self._user, for example return its name.
        return self._user.name

您已经声明将首先调用set_user,因此,如果用户为None,则将获得NoUserException
如果我在写这篇文章,我不会在MyClass中进行NoneType检查,如果用户是None,我也不会调用set_user

m = MyClass()
user = ...
if user:
   m.set_user(user)
   ... # anything else with `m`
else:
   # here is where you would get an error

相关问题