- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我在 Python 3 中有以下代码:
class Position:
def __init__(self, x: int, y: int):
self.x = x
self.y = y
def __add__(self, other: Position) -> Position:
return Position(self.x + other.x, self.y + other.y)
但我的编辑器 (PyCharm) 说无法解析引用 Position
(在 __add__
方法中)。我应该如何指定我希望返回类型为 Position
类型?
编辑:我认为这实际上是一个 PyCharm 问题。它实际上在其警告和代码完成中使用了这些信息。
但如果我错了,请纠正我,并且需要使用其他语法。
最佳答案
TL;DR:从今天(2019 年)开始,在 Python 3.7+ 中,您可以使用“ future ”语句from __future__ import annotations
启用此功能。
(from __future__ import annotations
可能会成为 Python future 版本的默认行为,was going 将成为 Python 3.10 的默认行为。但是, 3.10 was reverted 在最后一刻的变化,现在可能根本不会发生。)
在 Python 3.6 或更低版本中,您应该使用字符串。
我猜你遇到了这个异常:
NameError: name 'Position' is not defined
这是因为必须先定义 Position
,然后才能在注解中使用它,除非您将 Python 与 PEP 563 一起使用。已启用更改。
从 __future__ 导入注释
Python 3.7 引入 PEP 563: postponed evaluation of annotations .使用 future 语句 from __future__ import annotations
的模块将自动将注解存储为字符串:
from __future__ import annotations
class Position:
def __add__(self, other: Position) -> Position:
...
这已计划成为 Python 3.10 中的默认设置,但现在已推迟此更改。由于 Python 仍然是一种动态类型语言,因此在运行时不会进行类型检查,因此键入注释应该不会影响性能,对吧?错误的!在 Python 3.7 之前,打字模块曾经是 one of the slowest python modules in core所以对于涉及导入 typing
模块的代码,您将看到 up to 7 times increase in performance当您升级到 3.7 时。
According to PEP 484 ,您应该使用字符串而不是类本身:
class Position:
...
def __add__(self, other: 'Position') -> 'Position':
...
如果您使用 Django 框架,这可能很熟悉,因为 Django 模型也使用字符串进行前向引用(外键定义,其中外部模型是 self
或尚未声明)。这应该适用于 Pycharm 和其他工具。
PEP 484 和 PEP 563 的相关部分,省去你的旅行:
Forward references
When a type hint contains names that have not been defined yet, that definition may be expressed as a string literal, to be resolved later.
A situation where this occurs commonly is the definition of a container class, where the class being defined occurs in the signature of some of the methods. For example, the following code (the start of a simple binary tree implementation) does not work:
class Tree:
def __init__(self, left: Tree, right: Tree):
self.left = left
self.right = rightTo address this, we write:
class Tree:
def __init__(self, left: 'Tree', right: 'Tree'):
self.left = left
self.right = rightThe string literal should contain a valid Python expression (i.e., compile(lit, '', 'eval') should be a valid code object) and it should evaluate without errors once the module has been fully loaded. The local and global namespace in which it is evaluated should be the same namespaces in which default arguments to the same function would be evaluated.
和 PEP 563:
Implementation
In Python 3.10, function and variable annotations will no longer be evaluated at definition time. Instead, a string form will be preserved in the respective
__annotations__
dictionary. Static type checkers will see no difference in behavior, whereas tools using annotations at runtime will have to perform postponed evaluation....
Enabling the future behavior in Python 3.7
The functionality described above can be enabled starting from Python 3.7 using the following special import:
from __future__ import annotations
Position
在类定义之前,放置一个虚拟定义:
class Position(object):
pass
class Position(object):
...
这将摆脱 NameError
甚至看起来还可以:
>>> Position.__add__.__annotations__
{'other': __main__.Position, 'return': __main__.Position}
是吗?
>>> for k, v in Position.__add__.__annotations__.items():
... print(k, 'is Position:', v is Position)
return is Position: False
other is Position: False
您可能想尝试一些 Python 元编程魔法并编写一个装饰器对类定义进行猴子补丁以添加注释:
class Position:
...
def __add__(self, other):
return self.__class__(self.x + other.x, self.y + other.y)
装饰者应该负责相当于这个:
Position.__add__.__annotations__['return'] = Position
Position.__add__.__annotations__['other'] = Position
至少看起来是对的:
>>> for k, v in Position.__add__.__annotations__.items():
... print(k, 'is Position:', v is Position)
return is Position: True
other is Position: True
可能太麻烦了。
关于python - 如何键入提示具有封闭类类型的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33533148/
我的 friend 编写了一个程序,它比较随机排列的骰子面,以找到分布最均匀的面——尤其是当面不仅仅是序列时。 我将他的程序翻译成 haskell 是因为我一直在寻找一个理由来让别人知道 haskel
我需要对表单中的某些字段进行评论/提示。我的想法是在模型中描述它,就像attributeLabels一样。我该怎么做? 然后它会是理想的,如果 Gii 模型(和 Crud)生成器直接从 mysql 列
我们使用 FastReport 来生成报告。事实上,我们为访问源代码付费。 我们目前使用的是 FastReport 的最新稳定版本。虽然它对于我们的生产来说足够稳定,但每当我编译时,我都会看到以下内容
我需要创建一个对话框/提示,包括用于用户输入的文本框。我的问题是,确认对话框后如何获取文本?通常我会为此创建一个类,将文本保存在属性中。不过我想使用 XAML 设计对话框。因此,我必须以某种方式扩展
我想提示用户是否要执行操作(删除) - 用警报框说"is"或“否”,如果是,则运行删除脚本,如果否,则不执行任何操作 我不太了解 javascript,因此是否有人可以使用 javascript 获得
所以我正在编写一个简单的 JS 代码。我们刚刚开始学习函数。我需要创建一个名为“printStars”的函数。 我需要从用户那里获取一个号码,并根据该号码打印“*”。 这就是我所做的:
我在我的页面上添加了一个提示,但它在页面加载之前加载了。如何仅在整个页面可见时才显示消息? 这是我的提示: if (name == null || name == "") { txt == "No
我在我的页面上添加了一个提示,但它在页面加载之前加载了。如何仅在整个页面可见时才显示消息? 这是我的提示: if (name == null || name == "") { txt == "No
我正在自定义我的 zsh 提示,并发现以下内容来检查是否有任何后台作业: if [[ $(jobs | wc -l) -gt 0 ]]; then # has background job(s)
这个问题在这里已经有了答案: JavaScript object: access variable property by name as string [duplicate] (3 个答案) pa
我正在尝试用 javascript 制作一个简单的数学练习程序。在提示警报中给出不同的值,并将答案与用户输入进行比较。这是代码: Calculations generate(); functio
在这段代码中,尽管我使用了文本对齐属性在“编辑文本” View 的中心设置“提示”。但它无法正常工作。 最佳答案 尝试 关于android - 如何在编辑文本的中心对齐文本(提示),我们在Sta
我正在尝试让我的 EditText 显示一个提示,例如“请在此处输入答案”,当用户点击 EditText 以键入他们的答案时,文本应该消失并留空,以便他们在其中输入答案. 截至目前,这就是我的 .xm
我当前的 android 应用程序中有两个微调器,我想要一个默认值,例如 editText 的 android:hint 功能。有没有办法这样做,但不会将提示添加到填充微调器的字符串数组。例如从微调器
如果我的表单已完全填写,我如何提示“感谢您填写表单,“name”!” function submit_onclick() { if(confirm("Thanks for completing t
我刚刚了解了prompt()命令;我知道 Prompt() 命令以字符串的形式返回用户输入。我正在搞乱下面的程序,我输入了Per“Dead”Ohlin作为男性名字。为什么这有效并且没有引起任何问题?
void openUpNow(FILE *x, FILE *y) { x = fopen("xwhatever", "r"); y = fopen("ywhatever", "r");
我有一个作业正在处理,但我在使用 prompt() 方法时遇到了问题。我看到我可以做一个提示,但我需要几个并且有数量。 例如... 我创建了一个 HTML 表格,其中包含许多艺术家和包含 DVD、CD
我正在学习 Big Nerd Ranch 的 iOS Programming, 2nd Edition,我已经来到第 4 章挑战:标题。该练习暗示我感到困惑;它说我需要做一些我认为不需要做的事情。 到
抱歉,如果这是微不足道的,但我没有找到任何解决此问题的建议。我在 Ubuntu 上,我的 Yii 项目需要 PHPUnit。我已经安装了 PHPUnit 两次,方法是下载 phpunit.phar 并
我是一名优秀的程序员,十分优秀!