PyCharm中的“未解决的属性引用”

时间:2018-11-03 12:29:08

标签: python pycharm

即使代码运行正常,我在PyCharm中也收到 def bfs(self, start, end): visited = {start} # visited set contains int indices start_node = self.Node(start) q = deque() q.append(start_node) # deque contains Node objects while q: cur_node = q.popleft() # Node object if cur_node.idx == end: return cur_node for edge in self.get_out_edges(cur_node): # HERE IS WHERE I GET THE WARNING: child = self.Node(edge.get_opposite_node(i)) child_idx = child.idx if child_idx not in visited: visited.add(child_idx) q.append(child) child.parent = cur_node return None def get_out_edges(self, node): return self.adj[node.idx] def add_edge(self, line): # line is just a string from the input file (v, u, w) = [int(x) for x in line.split()] e = Edge(v,u,w) self.adj[v].append(e) self.adj[u].append(e) self.edges.append(e) 警告。

这是代码的相关部分:

self.adj

self.adj = [[] for _ in range(N)]是列表的列表:Edge,稍后由类class Edge: def __init__(self, v, u, w): self.v = v self.u = u self.w = w def get_node(self): return self.v def get_opposite_node(self, k=None): return self.u if k == self.v or k is None else self.v 的边缘填充:

self.adj[i]

因此,基本上,虽然Edge包含{{1}},但是PyCharm认为它包含list(?)。是否有办法“说服” PyCharm并非如此?

1 个答案:

答案 0 :(得分:0)

PyCharm感到困惑,因为您已明确声明adjlist(空)list s中的adj。不能断言您随后用理解get_opposite_node()的对象覆盖了get_opposite_node()的每个元素。但它确实知道您无法list adj

您可以通过声明list包含None的{​​{1}}而非空list的{​​{1}}来解决此问题。以下内容可能会有所澄清:

list

输出:

class RealEdge:
    def get_something(self):
        return "something"


class SomeEdgyThing:
    def __init__(self, size):
        self.adj = [[] for _ in range(size)]


class SomeOtherEdgyThing:
    def __init__(self, size):
        self.adj = [None for _ in range(size)]


class ReallyEdgyThing:
    def __init__(self, size):
        self.adj = [RealEdge() for _ in range(size)]


my_complicated_thing = SomeEdgyThing(7)
for i in range(len(my_complicated_thing.adj)):
    my_complicated_thing.adj[i] = RealEdge()
# PyCharm warning:
#     Unresolved attribute reference 'get_something' for class 'list'
# Runs fine, because we overwrote all the values in adj
# with RealEdges instead of lists.
print(my_complicated_thing.adj[1].get_something())

my_thing = SomeEdgyThing(7)
try:
    # PyCharm warning:
    #     Unresolved attribute reference 'get_something' for class 'list'
    # Also a runtime error:
    #     AttributeError: 'list' object has no attribute 'get_something'
    print(my_thing.adj[1].get_something())
except AttributeError as e:
    print(e)

my_other_thing = SomeOtherEdgyThing(7)
try:
    # PyCharm doesn't complain.
    # Does it assume NoneType is part of a union type...?
    # Runtime error:
    #     AttributeError: 'NoneType' object has no attribute 'get_something'
    print(my_other_thing.adj[1].get_something())
except AttributeError as e:
    print(e)

real_thing = ReallyEdgyThing(7)
# No error
print(real_thing.adj[1].get_something())

我怀疑您真的不需要写something 'list' object has no attribute 'get_something' 'NoneType' object has no attribute 'get_something' something ,而self.adj = [[] for _ in range(N)]同样有用,并且会导致警告消失。

现在,您仍然会遇到这样的情况,即您的代码以某种方式以错误的顺序运行,并且尝试对尚未更新为包含实数的self.adj = [None for _ in range(N)]成员调用get_opposite_node() adj。您只是不再受到警告。因此,我建议将这些调用包装在Edge块中。