相关疑难解决方法(0)

如何注释类方法返回该类的实例

使用PEP 484,有没有办法注释 classmethod 返回该类的实例?

例如

@dataclass
class Bar:

    foo: str

    @classmethod
    def new_from_foo(cls, foo) -> Bar
        ...
Run Code Online (Sandbox Code Playgroud)

或者

    @classmethod
    def new_from_foo(cls, foo) -> cls
Run Code Online (Sandbox Code Playgroud)

python type-hinting python-typing

6
推荐指数
1
解决办法
1596
查看次数

如何注释返回 self 的 Python3 方法?

函数注释:PEP-3107

背景:我是 Linux 上使用 CPython 3.4x 的 PyCharm 用户。我发现注释函数参数和返回类型很有帮助。当我使用这些方法时,IDE 可以更好地提示。

问题:对于自链方法,如何注释方法返回值?如果我使用类名,Python 会在编译时抛出异常:NameError: name 'X' is not defined

示例代码:

class X:
    def yaya(self, x: int):
        # Do stuff here
        pass

    def chained_yaya(self, x: int) -> X:
        # Do stuff here
        return self
Run Code Online (Sandbox Code Playgroud)

作为一个技巧,如果我把X = None它放在类声明之前,它就可以工作。但是,我不知道这种技术是否有不可预见的负面影响。

annotations method-chaining python-3.x

5
推荐指数
1
解决办法
1579
查看次数

提示返回自己类实例的方法的正确方法是什么?

我想使Foo成为一个不变的对象。当我“扩展” foo时,我想获得一个Foo的新实例。我希望输入如下提示:

class Foo(object):
    def extend(self, item:str) -> Foo:
        pass
Run Code Online (Sandbox Code Playgroud)

看起来不错,但是IntelliJ并不同意。我在第二行的Foo下面得到一个红色的下划线。错误消息是:未解析的引用'Foo'

我有点明白了这是什么意思:在tyme上,我们正在解析第2行,但是我们还没有对象Foo,因此解释器不知道Foo是什么意思。

但奇怪的是,对于PyCharm(但无效的python),这个非常不令人满意的替代方法就足够了:

class Foo(object):
    def extend(self, item:str) -> Foo_:
        pass

Foo_ = Foo
Run Code Online (Sandbox Code Playgroud)

那么有没有有效的方法来做到这一点?我如何在类型提示注释中说特定方法返回新的self实例。

我在带有PyCharm插件的IntelliJ的最新版本上使用Python 3.5。

python intellij-idea pycharm

5
推荐指数
0
解决办法
213
查看次数

我可以在 Python 类型提示中使用 __qualname__ 并推迟注释评估吗?

我喜欢用于__qualname__工厂式类方法的返回类型注释,因为它不会对类名进行硬编码,因此可以保持子类的工作(参见此答案)。

class Foo:
    @classmethod
    def make(cls) -> __qualname__:
        return cls()
Run Code Online (Sandbox Code Playgroud)

目前这似乎工作正常,但我不确定通过推迟注释评估(PEP 563)这是否仍然可能:PEP

注释只能使用模块范围中存在的名称,因为使用本地名称的延迟评估不可靠(唯一的例外是由 解析的类级别名称typing.get_type_hints())。

政治公众人物还表示

该函数会自动解析函数和类get_type_hints()的正确值。globalns它还自动提供正确localns的课程。

然而,下面的代码

from __future__ import annotations

import typing

class Foo():
    @classmethod
    def make(cls) -> __qualname__:
        return cls()

print(typing.get_type_hints(Foo.make))
Run Code Online (Sandbox Code Playgroud)

失败了

  File "qualname_test.py", line 11, in <module>
    print(typing.get_type_hints(Foo.make))
  File "/var/local/conda/envs/py37/lib/python3.7/typing.py", line 1004, in get_type_hints
    value = _eval_type(value, globalns, localns)
  File "/var/local/conda/envs/py37/lib/python3.7/typing.py", line 263, in _eval_type
    return t._evaluate(globalns, localns)
  File "/var/local/conda/envs/py37/lib/python3.7/typing.py", …
Run Code Online (Sandbox Code Playgroud)

python language-lawyer

5
推荐指数
1
解决办法
1045
查看次数

今天我还需要 __future__ 吗?

我对Python模块的用例不是很熟悉__future__,只是我在一些在线文章的演示代码中看到过它。读完之后,我想这与面向未来的现有代码有关?我承认我并不完全理解我正在读的内容。根据官方文档,其功能为:

\n
\n
    \n
  • 为了避免混淆分析导入语句并期望找到它们\xe2\x80\x99正在导入的模块的现有工具。
  • \n
  • 为了确保 future 语句在 2.1 之前的版本下运行至少会产生运行时异常(future的导入将会失败,因为在 2.1 之前没有该名称的模块)。
  • \n
  • 记录何时引入不兼容的更改,以及何时将这些更改强制为 \xe2\x80\x94 或 \xe2\x80\x94。这是一种可执行文档的形式,可以通过导入future并检查其内容以编程方式进行检查。
  • \n
\n
\n

第1点是什么意思?是不是说如果解释器读取导入语句,但没有找到它正在导入的模块,那么拥有import __future__将阻止它抛出错误?

\n

随着 Python 2.7 于 2020 年 1 月 1 日正式终止,如果我无意在我的 Python 3 代码中支持 Python 2 环境,那么我认为第 2 点与我无关。

\n

我猜第 3 点是为了……调试?这就是它想表达的吗?

\n

我注意到到目前为止我读过的所有文章都至少是五年前的。所有示例都重点关注处理 Python 2 向后兼容性的 Python 3 代码,特别print//. 但正如我所说,我无意支持 Python 2。

\n

Python 中 __future__ 的用途是什么,如何/何时使用它,以及它是如何工作的

\n

import __future那么,如果不打算向后兼容 Python 2,我什么时候需要在 …

python python-3.x

5
推荐指数
2
解决办法
3880
查看次数

我可以使用 Typing_extensions 中的实验类型吗?

更具体:

要解决诸如如何使用封闭类的类型键入提示方法之类的问题?
PEP 673介绍typing.Self。PEP 是一个草案,但目前它是 Typing_extensions 4.0.0 中的实验类型

我尝试在 python 3.8 中使用它

@dataclasses.dataclass
class MenuItem:
    url: str
    title: str
    description: str = ""
    items: typing.List[typing_extensions.Self] = dataclasses.field(default_factory=list)
Run Code Online (Sandbox Code Playgroud)

但它提高了

TypeError: Plain typing_extensions.Self is not valid as type argument
Run Code Online (Sandbox Code Playgroud)

我可以只使用文字字符串“MenuItem”来代替。但我想知道为什么这不起作用。

python python-typing

5
推荐指数
1
解决办法
3747
查看次数

返回类的类方法

我正在玩python的3.5类型提示.我想知道如何键入提示类方法的返回类型.

这就是我的想法:

>>> class A():
    @classmethod
    def a(cls) -> A:
        pass

Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    class A():
  File "<pyshell#24>", line 3, in A
    def a(cls) -> A:
NameError: name 'A' is not defined
Run Code Online (Sandbox Code Playgroud)

显然它不起作用.我想一种方法是做某种"前向声明",如下所示:

>>> class A():
    pass

>>> class A():
    @classmethod
    def a(cls) -> A:
        pass
Run Code Online (Sandbox Code Playgroud)

但这并不觉得"pythonic".人们通常如何解决这个问题?

python type-hinting python-3.5

4
推荐指数
1
解决办法
1076
查看次数

类方法返回错误的类型提示 - 名称未定义?

下面的类有一个类方法create(),它作为返回类型的类型提示,用于创建该类的实例。

class X:
   @classmethod
   def create(cls) -> X:
     pass
Run Code Online (Sandbox Code Playgroud)

然而,却出现了以下错误?

名称错误:名称“X”未定义

python pylint python-typing

4
推荐指数
1
解决办法
2465
查看次数

为什么在 Python 中没有提示 self 类型

我一直在研究类型提示我的代码,但注意到 Python 程序员通常不会self在他们的程序中键入提示

即使我查看文档,它们似乎也没有输入提示 self,请参见 此处。这是来自 3.10 版的前向声明

    def __init__(self, value: T, name: str, logger: Logger) -> None:
Run Code Online (Sandbox Code Playgroud)

我可以理解为什么在 3.7 中引入带有前向声明的类型注释之前,这是一个问题

更多信息 在这里这里


这对我来说似乎有用的原因是 mypy 似乎能够捕捉到这个问题的错误

例子:

from __future__ import annotations

class Simple(object):
    def __init__(self: Simple):
        print(self.x)
          
Run Code Online (Sandbox Code Playgroud)

将从 mypy 返回这个

mypy test.py 
test.py:5: error: "Simple" has no attribute "x"
Found 1 error in 1 file (checked 1 source file)
Run Code Online (Sandbox Code Playgroud)

如果您从中删除类型,则self变为

Success: no issues found in 1 source file

Run Code Online (Sandbox Code Playgroud)
  • 是否有self未注释的原因,或者这是唯一的约定?
  • 是否有我遗漏的权衡或者我的注释self …

python mypy

3
推荐指数
1
解决办法
129
查看次数

子类中返回值的类型提示

我正在编写一个 CustomEnum 类,我想在其中添加一些辅助方法,然后子类化我的 CustomEnum 的类可以使用这些方法。其中一种方法是返回一个随机枚举值,这就是我被卡住的地方。该函数按预期工作,但在类型提示方面,我无法想出一种说法“返回类型与 cls 类型相同”

我相当确定其中TypeVar涉及一些或类似的魔法,但由于我从未使用过它们,因此我从未花时间弄清楚它们。

class CustomEnum(Enum):
    @classmethod
    def random(cls) -> ???:
        return random.choice(list(cls))


class SubclassingEnum(CustomEnum):
    A = "a"
    B = "b"

random_subclassing_enum: SubclassingEnum
random_subclassing_enum = SubclassingEnum.random() # Incompatible types in assignment (expression has type "CustomEnum", variable has type "SubclassingEnum")
Run Code Online (Sandbox Code Playgroud)

有人可以帮助我或给我一个关于如何进行的提示吗?

谢谢!

python type-hinting mypy

3
推荐指数
2
解决办法
112
查看次数