社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python将属性保留为未赋值,并使用省略号或None+float类型提示

Intrastellar Explorer • 5 年前 • 1475 次点击  

我想声明一个实例属性,类型暗示为 float ,初始化时不分配值。该值是在运行时、实例初始化后(也称为 __init__ ).

this answer ,我可以将值设置为 None . 但是,我的IDE( PyCharm PyTypeChecker 旗帜,说 Expected type 'float', got type 'None' instead .

我发现如果将值设置为省略号(建议 this answer ),aka值= ... ,PyCharm不再抱怨了。

这里的最佳做法是什么? ... ?


示例代码

class SomeClass:

    def __init__(self):
        """Initialize with an unassigned value."""

        # PyCharm complains here
        self._unassigned_val = None  # type: float

        # PyCharm doesn't complain here
        self._unassigned_val2 = ...  # type: float

    def called_during_runtime(self) -> None:
        """This gets called after __init__ has run."""
        self._unassigned_val = 1.0
        self._unassigned_val2 = 1.0

在我的IDE中是什么样子的:

Sample Code In PyCharm


  • PyCharm社区版 2019.2.5
  • 3.6
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/52970
 
1475 次点击  
文章 [ 1 ]  |  最新文章 5 年前
Michael0x2a
Reply   •   1 楼
Michael0x2a    5 年前

对于简单的情况,实际上可以不用在构造函数中执行任何操作:如果执行以下操作,mypy和Pycharm将继续正确推断字段的类型:

class SomeClass:
    def called_during_runtime(self) -> None:
        self._unassigned_val = 1.0

如果您的函数以足够复杂的方式为该字段赋值,则类型检查器可能会阻塞,不知道该做什么。在这种情况下,您可以使用 Variable annotations 如果您使用的是Python3.6或更高版本:

class SomeClass:
    _unassigned_val: float

    def called_during_runtime(self) -> None:
        self._unassigned_val = 1.0

这完全等同于运行时的第一种方法。

如果需要支持较旧版本的Python,则可以使用另一种技术创建一个“假”sentinel值,该值被赋予一种 Any ,全动态类型:

from typing import Any

BOGUS = object()  # type: Any

class SomeClass:
    def __init__(self) -> None:
        self._unassigned_val = BOGUS  # type: float

    def called_during_runtime(self) -> None:
        self._unassigned_val = 1.0

如果您改变主意并决定偏向类型检查器,请更积极地处理其警告,您可以始终声明您的值可以是 任何一个 浮动或无:

from typing import Optional

class SomeClass:
    def __init__(self) -> None:
        self._unassigned_val = None  # type: Optional[float]

    def called_during_runtime(self) -> None:
        self._unassigned_val = 1.0

    def get_with_default(self, default: float) -> float:
        if self._unassigned_val is None:
            return default
        else:
            return self._unassigned_val

注意,然后可以使用 self._unassigned_val is not None , self._unassigned_val is None ,或 isinstance(self._unassigned_val, float) 在if语句中检查,并断言让类型检查器有条件地缩小字段的类型。

最后一种方法是我个人所做的:我是类型检查程序的粉丝,并且设置我的工具来非常积极地检测潜在的问题。

关于省略号的最后一个注意事项:使用省略号作为占位符仅适用于存根,并且在处理诸如 Protocols abstract classes --基本上,如果您在运行时从未实际使用字段/方法参数/任何东西的值。