我已经在一个类中定义了一个属性(yYEAR),并使用一个全局变量(YEAR)对其进行了初始化。 当我在类中调用该方法时,即使没有给它分配任何值,它也会更新全局变量。 为什么会这样发生? 错误是使用类变量的定义的不正确位置来完成的。
JAN = MAR =MAY =JUL =AUG= OCT =DEC=[0]*31
APR=JUN=SEP=NOV=[0]*30
FEB=[0]*28
YEAR = [JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC]
class load:
yYEAR=YEAR
def __init__(self, DURATION, LTYPE):
self.DURATION=DURATION
self.LTYPE= LTYPE
def daily247(self):
if self.LTYPE==1 :
for month in range(len(self.yYEAR)):
for day in range(len(self.yYEAR[month])):
self.yYEAR[month][day]= 1
else:
self.yYEAR= YEAR
self.dispLoad()
def dispLoad(self):
print(self.yYEAR[0])
print(self.yYEAR[1])
event1= load(10,1)
event1.daily247() # Expected result ones in all nested elements in YEAR
event2= load(10,0)
event2.daily247() # Expected result zeros in all nested elements in YEAR
print(YEAR[1]) # expected result is to have zeros for all elements
答案 0 :(得分:2)
您的YEAR
是列表类型。 Python的列表是可变的。将其全部大写会意味着它一旦设置就不应更改(“常量”),但这只是Python完全不实施的约定。
如果您想要一个可以更改的单独副本,而不是对全局变量的引用,请执行
改为yYEAR = YEAR[:]
。然后副本将属于该类。
[:]
是切片符号,因为您没有指定边界,所以它仅复制整个内容。
yYEAR = YEAR.copy()
也可以,但是在列表的情况下,前者更为常规。
如果要按实例复制,请在__init__
内设置属性,例如
self.yYEAR = YEAR[:]
。确实,您可以将其拼写为self.year
。那会更pythonic。
您可以使用不可变的元组而不是列表来防御性地编码常量,以保护自己免受意外突变的影响。然后,您可以从中创建本地列表,例如yYear = [*YEAR]
,或者如果您仍在使用旧版本的Python,yYear = list(YEAR)
也可以使用。但是请注意,不可变的元组仍然可以包含可变元素,因此也不会完全强制执行const正确性。
还请注意,像APR=JUN=SEP=NOV=[0]*30
这样的语法意味着这四个月中的所有月份都将引用同一列表对象。
答案 1 :(得分:0)
该错误是由于提到的Python可变列表“ glitch”造成的。但是,使用[:]
或.copy()
复制列表在这种情况下不起作用,因为原始列表是2D。
对2D列表进行深度复制可以解决此问题。
import copy
并使用deepcopy()
class load:
def __init__(self, DURATION, LTYPE):
self.DURATION=DURATION
self.LTYPE= LTYPE
self.yYEAR = copy.deepcopy(YEAR)