即使代码运行正常,我在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并非如此?
答案 0 :(得分:0)
PyCharm感到困惑,因为您已明确声明adj
为list
(空)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
块中。