gpt4 book ai didi

python-3.x - PyCharm: 'Function Doesn' t 返回任何内容'

转载 作者:行者123 更新时间:2023-12-03 07:43:51 26 4
gpt4 key购买 nike

我今天刚刚开始使用 PyCharm Community Edition 2016.3.2。每次我从函数 at_square 赋值时,它警告我“函数 at_square”不返回任何内容,但在每个实例中它肯定会返回任何内容,除非在执行期间引发错误,并且该函数的每次使用都按预期运行。我想知道为什么 PyCharm 认为没有,以及我是否可以采取任何措施来纠正它。 (我知道有一个选项可以抑制该特定函数的警告,但它是通过在函数上方的代码中插入注释行来实现的,而且我发现必须记住在最后将其删除也很烦人项目。)

这是有问题的函数:

def at_square(self, square):
""" Return the value at the given square """
if type(square) == str:
file, rank = Board.tup_from_an(square)
elif type(square) == tuple:
file, rank = square
else:
raise ValueError("Expected tuple or AN str, got " + str(type(square)))

if not 0 <= file <= 7:
raise ValueError("File out of range: " + str(file))
if not 0 <= rank <= 7:
raise ValueError("Rank out of range: " + str(rank))

return self.board[file][rank]

如果重要的话,更准确地说,这是对象的方法。我坚持使用“函数”这个术语,因为这是 PyCharm 使用的语言。

我唯一的想法是,我对错误引发的使用可能会让 PyC​​harm 感到困惑,但这似乎太简单了。 (请随意批评我提出的错误,因为我不确定这是惯用的方法。)

更新:有趣的是,如果我完全删除返回行,警告就会消失,并在我将其放回去时立即返回。如果我替换 self.board[file][rank] 它也会消失具有像 8 这样的常量值。改变filerank设置为常量值并不会消除警告,因此我认为 PyCharm 在某种程度上对 self.board 的性质感到困惑,这是其他 8 个列表的列表。

更新:根据@StephenRauch的建议,我创建了一个最小的示例,反射(reflect)了与at_square完成的数据分配相关的所有内容。 :

class Obj:
def __init__(self):
self.nested_list = [[0],[1]]

@staticmethod
def tup_method(data):
return tuple(data)

def method(self,data):
x,y = Obj.tup_method(data)
return self.nested_list[x][y]

def other_method(self,data):
value = self.method(data)
print(value)

x = Obj()
x.other_method([1,2])

PyCharm 不会对此发出任何警告。在 at_square ,我尝试将每一行注释为以下两行:

def at_square(self, square):
file, rank = Board.tup_from_an(square)
return self.board[file][rank]

PyCharm 给出了相同的警告。如果我只留下返回线,那么警告才会消失。 PyCharm 似乎对 file 的同时分配感到困惑和rank通过tup_from_an 。以下是该方法的代码:

@staticmethod
def tup_from_an(an):
""" Convert a square in algebraic notation into a coordinate tuple """
if an[0] in Board.a_file_dict:
file = Board.a_file_dict[an[0]]
else:
raise ValueError("Invalid an syntax (file out of range a-h): " + str(an))

if not an[1].isnumeric():
raise ValueError("Invalid an syntax (rank out of range 1-8): " + str(an))
elif int(an[1]) - 1 in Board.n_file_dict:
rank = int(an[1]) - 1
else:
raise ValueError("Invalid an syntax (rank out of range 1-8): " + str(an))

return file, rank

更新:在其构造函数中,类 Board (这是所有这些方法的父类)将实例的引用保存在静态变量 instance 中。 。 self.at_square(square)给出警告,而 Board.instance.at_square(square)才不是。我仍然会在适当的情况下使用前者,但这可以阐明 PyCharm 的想法。

最佳答案

如果返回值静态计算为None,则 PyCharm 假定缺少返回值。如果使用 None 初始化值,并稍后更改其类型,则可能会发生这种情况。

class Foo:
def __init__(self):
self.qux = [None] # infers type for Foo().qux as List[None]

def bar(self):
return self.qux[0] # infers return type as None

此时,Foo.bar静态推断为 (self: Foo) -> None通过副作用动态更改 qux 的类型不会更新此内容:

foo = Foo()
foo.qux = [2] # *dynamic* type of foo.bar() is now ``(self: Foo) -> int``
foo_bar = foo.bar() # Function 'bar' still has same *static* type

问题在于您正在通过动态分配的实例属性覆盖静态推断的类属性。一般来说,静态分析根本无法捕捉到这一点。

您可以使用显式类型提示来修复此问题。

import typing


class Foo:
def __init__(self):
self.qux = [None] # type: typing.List[int]

def bar(self):
return self.qux[0] # infers return type as int

从Python 3.5开始,您还可以使用inline type hints 。这些对于返回类型特别有用。

import typing


class Foo:
def __init__(self):
# initial type hint to enable inference
self.qux: typing.List[int] = [None]

# explicit return type hint to override inference
def bar(self) -> int:
return self.qux[0] # infers return type as int

请注意,在有效的情况下依赖推理仍然是一个好主意!仅注释 self.qux 可以让以后更轻松地更改类型。注释 bar 对于文档和覆盖不正确的推断最有用。

如果需要支持3.5之前的版本,也可以使用 stub files 。假设您的类位于 foomodule.py 中,创建一个名为 foomodule.pyi 的文件。在里面,只需添加带注释的字段和函数签名即可;你可以(并且应该)忽略尸体。

import typing


class Foo:
# type hint for fields
qux: typing.List[int]

# explicit return type hint to override inference
def bar(self) -> int:
...

关于python-3.x - PyCharm: 'Function Doesn' t 返回任何内容',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42127461/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com