首页 > 解决方案 > 创建的对象未使用更新的全局变量值

问题描述

我有以下代码main.py

import json
from data import message    # data.py
from definitions import *   # definitions.py

waypoints=[]
stations=[]
genes = []

jsonObj = json.loads(message) # from data.py

for item in jsonObj:
  location = Location(id=item["id"], name=item["name"], lat=item["lat"], lon=item["lon"])
  if ("is-start" in item) or ("is-end" in item):
    location.isWaypoint = True
    if "is-start" in item:
      start = location
    else:
      end = location
  else:
    genes.append(location)
    if "is-waypoint" in item:
      location.isWaypoint = True
      waypoints.append(location)
    else:
      stations.append(location)

然后,我有以下代码definitions.py

from haversine import haversine

start = None
end = None
distMatrix = {}

def distBtwn(loc1, loc2):
  dist = 0
  pair = frozenset((loc1.id, loc2.id))
  if pair in distMatrix:
    dist = distMatrix[pair]
  else:
    coords1 = (loc1.lat, loc2.lon)
    coords2 = (loc2.lat, loc2.lon)
    dist = haversine(coords1, coords2)
    distMatrix[pair] = dist
  return dist

class Location:
  def __init__(self, id, name, lat, lon):
    self.id = id
    self.name = name
    self.lat = lat
    self.lon = lon
    self.isWaypoint = False

  def __repr__(self):
    rep = ""
    if self.isWaypoint:
      rep += "Waypoint "
    else:
      rep += "Station "
    rep += "%d: %s (%f, %f)" % (self.id, self.name, self.lat, self.lon)
    return rep

class Fitness:
  def __init__(self, route):
    self.route = route
    self.distance = 0.0
    self.fitness = 0.0

  def routeDistance(self):
    if self.distance = 0.0:
      global start
      global end
      print(start)
      print(self.route[0])
      print(self.route[-1])
      print(end)
      pathDistance = distBtwn(start, self.route[0]) + distBtwn(self.route[-1], end)
      for i in range(len(self.route) - 1):
        pathDistance += distBtwn(self.route[i], self.route[i + 1])
      self.distance = pathDistance
  return self.distance

我运行main.py,然后在 shell 中输入以下内容,这会引发错误:

>>> start
Waypoint 0: startPoint (3.333333, 3.333333)
>>> end
Waypoint 2: endPoint (4.444444, 4.444444)
>>> route = [waypoints[0], stations[15], waypoints[1]]
>>> fitA = Fitness(route)
>>> fitA.routeDistance()
None
Waypoint 1: waypointA (1.111111, 1.111111)
Waypoint 3: waypointC (2.222222, 2.222222)
None
Traceback (most recent call last):
  File "<pyshell#78>", line 1, in <module>
    fitA.routeDistance()
  File "definitions.py", line 54, in routeDistance
    pathDistance = distBtwn(start, self.route[0]) + distBtwn(self.route[-1], end)
  File "definitions.py", line 10, in distBtwn
    pair = frozenset((loc1.id, loc2.id))
AttributeError: 'NoneType' object has no attribute 'id'
>>> start
Waypoint 0: startPoint (3.333333, 3.333333)
>>> end
Waypoint 2: endPoint (4.444444, 4.444444)

基于上述,routeDistance()使用初始化的原始Nonestartend初始化,即使它们已被声明为全局变量。然而,当从 shell 调用时,这两个变量已经使用Location分配的对象正确更新。这里出了什么问题?

标签: python

解决方案


全局变量的作用域是一个模块。

例如,在foo.py

def set_variable(to):
    global variable
    variable = to
variable = None

并且bar.py

import foo

def get_variable():
    global variable  # Unnecessary, but to avoid confusion
    return variable

variable = 1
print(foo.variable)  # None
foo.set_variable(2)  # Sets `foo`'s global variable to `2`
print(get_variable())  # 1; `bar`'s global variable is still 1
print(foo.variable)  # 2; `foo`'s global variable is now `2`

您需要设置definitions.startdefinitions.stop


推荐阅读