Python 类属性 vs 全局变量

2024-06-02 06:11:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一个类中定义了一个属性(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

Tags: inselffordefloadelementsresultall
2条回答

这个错误是由于python的可变列表引起的,如“glitch”所述。但是,使用[:].copy()复制列表在这种情况下不起作用,因为原始列表是2D的

制作一个2D列表的深拷贝解决了这个问题。在

import copy

并使用deepcopy()为每个实例生成一个deepcopy

^{pr2}$

您的YEAR是列表类型。Python的列表是可变的。用大写字母拼写它意味着一旦设置(一个“常量”),就不应该更改它,但这只是一个Python根本没有强制执行的约定。在

如果您想要一个可以更改的单独副本,而不是对全局的引用,请执行
yYEAR = YEAR[:]。那么副本将属于该类。在

[:]是一种切片表示法,它只是复制整个内容,因为您没有指定边界。
yYEAR = YEAR.copy()也可以,但前者在列表的情况下更为传统。在

如果您想要每个实例的副本,请改为在__init__中设置属性,如
self.yYEAR = YEAR[:]。真的,你可以把它拼成self.year。那会更像Python。在

通过使用不可变元组而不是列表,您可以对常量进行更具防御性的编码,以防止意外的突变。然后,您可以从中创建本地列表,就像yYear = [*YEAR]或者如果您仍然使用旧版本的Python,yYear = list(YEAR)也可以。但是要注意,不可变元组仍然可以包含可变元素,因此这也不能完全强制实现const正确性。在


还要注意,像APR=JUN=SEP=NOV=[0]*30这样的语法意味着所有四个月都将引用同一个list对象。在

相关问题 更多 >