Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何键入一个类型为封闭类的方法?_Python_Python 3.x_Pycharm_Typing_Python 3.5 - Fatal编程技术网

Python 如何键入一个类型为封闭类的方法?

Python 如何键入一个类型为封闭类的方法?,python,python-3.x,pycharm,typing,python-3.5,Python,Python 3.x,Pycharm,Typing,Python 3.5,我在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)说,无法

我在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)说,无法解析参考位置(在
\uuuuuuuuuuuuuuuu添加
方法中)。我应该如何指定我期望返回类型为
Position

编辑:我认为这实际上是一个问题。它实际上在警告和代码完成中使用了这些信息


但是如果我错了,请纠正我,并且需要使用其他语法。

在解析类主体本身时,名称“Position”不可用。我不知道您是如何使用类型声明的,但是Python的PEP 484——如果使用这些类型提示,大多数模式都应该使用PEP 484,它表示您可以在此时将名称作为字符串:

def __add__(self, other: 'Position') -> 'Position':
    return Position(self.x + other.x, self.y + other.y)
检查-符合的工具将知道从那里打开类名并使用它。(请务必记住,Python语言本身不做这些注释——它们通常用于静态代码分析,或者可以有一个用于运行时类型检查的库/框架——但必须显式设置)


更新同样,从Python 3.7开始,检查-从Python 3.8开始,可以从uuu future uuu导入注释编写
,以推迟注释的评估-前向引用类应该可以直接工作。

在解析类主体本身时,名称“Position”不可用。我不知道您是如何使用类型声明的,但是Python的PEP 484—如果使用这些类型提示,大多数模式都应该使用PEP 484—表示此时可以将名称作为字符串:

def __add__(self, other: 'Position') -> 'Position':
    return Position(self.x + other.x, self.y + other.y)
检查-符合的工具将知道从那里打开类名并使用它。(请务必记住,Python语言本身不做这些注释——它们通常用于静态代码分析,或者可以有一个用于运行时类型检查的库/框架——但必须显式设置)


更新同样,从Python 3.7开始,检查-从Python 3.8开始,可以从uuu future uuu导入注释编写
,以推迟注释的评估-前向引用类应该可以直接工作。

TL;DR:如果您使用的是Python 3.10或更高版本,它就可以工作了。从今天(2019年)开始,在3.7+中,必须使用future语句(
from uuuu future\uuuuu import annotations
)打开此功能。在Python 3.6或更低版本中,使用字符串

我猜你得到了这个例外:

NameError: name 'Position' is not defined
这是因为必须先定义
Position
,然后才能在注释中使用它,除非您使用的是Python 3.10或更高版本

Python 3.7+:
来自未来导入注释
Python 3.7引入了一个模块,该模块使用来自uuu future\uuuuu导入注释的future语句
,将注释自动存储为字符串:

from __future__ import annotations

class Position:
    def __add__(self, other: Position) -> Position:
        ...
这将成为Python3.10中的默认设置。由于Python仍然是一种动态类型化语言,因此在运行时不会进行类型检查,因此类型注释应该不会对性能产生影响,对吗?错!在Python3.7之前,如果您
导入类型,您将看到在升级到3.7时,类型模块通常是如此


PythonTL;DR:如果您使用的是Python 3.10或更高版本,它就可以正常工作。从今天(2019年)起,在3.7+中,您必须使用future语句(
from uuuuu future\uuuuuuu导入注释
)打开此功能。在Python 3.6或更低版本中,使用字符串

我猜你得到了这个例外:

NameError: name 'Position' is not defined
这是因为必须先定义
Position
,然后才能在注释中使用它,除非您使用的是Python 3.10或更高版本

Python 3.7+:
来自未来导入注释
Python 3.7引入了一个模块,该模块使用来自uuu future\uuuuu导入注释的future语句
,将注释自动存储为字符串:

from __future__ import annotations

class Position:
    def __add__(self, other: Position) -> Position:
        ...
这将成为Python3.10中的默认设置。由于Python仍然是一种动态类型化语言,因此在运行时不会进行类型检查,因此类型注释应该不会对性能产生影响,对吗?错!在Python3.7之前,如果您
导入类型,您将看到在升级到3.7时,类型模块通常是如此


Python将类型指定为string很好,但是我们基本上绕过了解析器,这让我有点恼火。因此,您最好不要拼错这些文本字符串中的任何一个:

def __add__(self, other: 'Position') -> 'Position':
    return Position(self.x + other.x, self.y + other.y)
一个微小的变化是使用绑定的typevar,至少在声明typevar时只需编写一次字符串:

from typing import TypeVar

T = TypeVar('T', bound='Position')

class Position:

    def __init__(self, x: int, y: int):
        self.x = x
        self.y = y

    def __add__(self, other: T) -> T:
        return Position(self.x + other.x, self.y + other.y)

将类型指定为string很好,但总让我有点恼火,因为我们基本上绕过了解析器。因此,您最好不要拼错这些文本字符串中的任何一个:

def __add__(self, other: 'Position') -> 'Position':
    return Position(self.x + other.x, self.y + other.y)
一个微小的变化是使用绑定的typevar,至少在声明typevar时只需编写一次字符串:

from typing import TypeVar

T = TypeVar('T', bound='Position')

class Position:

    def __init__(self, x: int, y: int):
        self.x = x
        self.y = y

    def __add__(self, other: T) -> T:
        return Position(self.x + other.x, self.y + other.y)

如果可以接受基于字符串的类型提示,则也可以使用
\uuuu qualname\uuuu
项。它包含类的名称,并且在类定义的主体中可用

class MyClass:
    @classmethod
    def make_new(cls) -> __qualname__:
        return cls()

通过这样做,重命名类并不意味着修改类型提示。但我个人不希望智能代码编辑器能够很好地处理此表单。

当基于字符串的类型提示可以接受时,也可以使用
\uuuuuqalname\uuuqu
项。它包含类的名称,并且可以在类定义的主体中使用。

class MyClass:
    @classmethod
    def make_new(cls) -> __qualname__:
        return cls()

通过这样做,重命名类并不意味着修改类型提示。但我个人不希望智能代码编辑器能够很好地处理此表单。

如果您只关心修复
名称错误:未定义名称“位置”
,您可以将类名指定为字符串:

def __add__(self, other: 'Position') -> 'Position':
或者,如果您使用Python3.7或更高版本,请将以下行添加到
def __add__(self, other: 'Position') -> 'Position':
    return Position(self.x + other.x, self.y + other.y)
from typing import TypeVar

T = TypeVar('T', bound='Position')

class Position:

    def __init__(self, x: int, y: int):
        self.x = x
        self.y = y

    def __add__(self, other: T) -> T:
        return Position(self.x + other.x, self.y + other.y)
class MyClass:
    @classmethod
    def make_new(cls) -> __qualname__:
        return cls()
def __add__(self, other: 'Position') -> 'Position':
from __future__ import annotations
from __future__ import annotations

from typing import TypeVar

T = TypeVar('T', bound=Position)

class Position:
    
    def __init__(self, x: int, y: int):
        self.x = x
        self.y = y
    
    def __add__(self: T, other: Position) -> T:
        return type(self)(self.x + other.x, self.y + other.y)
    
    def copy(self: T) -> T:
        return type(self)(self.x, self.y)
class DynamicParent:
  def func(self):
    # roundabout way of returning self in order to have inherited type hints of the return
    # https://stackoverflow.com/a/64938978
    _self:self.__class__ = self
    return _self
class StaticParent:
  def func(self) -> 'StaticParent':
    return self
class StaticChild(StaticParent):
  pass

class DynamicChild(DynamicParent):
  pass

static_child = StaticChild()
dynamic_child = DynamicChild()