我正在关注Python Crash Course中的一个项目,该项目演示了如何使用CSV文件。下面的代码使用我认为的dates
对象成功填充datetime
列表。例如,这是dates
列表的第一个元素:datetime.datetime(2014, 1, 1, 0, 0)
。这是功能代码:
import csv
from datetime import datetime
filename = 'sitka_weather_2014.csv'
with open(filename) as f:
reader = csv.reader(f)
# Move onto the next row as the first contains no data
next(reader)
dates = []
for row in reader:
try:
date = datetime.strptime(row[0], "%Y-%m-%d")
except ValueError:
print(date, "missing data")
else:
dates.append(date)
print(dates[0])
此代码的输出为:2014-01-01 00:00:00
现在,我想用几个不同的文件实现这个项目,并用OO设计原则练习。我设置了一个父类WeatherData
,它有两个属性:一个名为data
的列表和一个名为filename
的字符串。 WeatherData
类将使用CSV文件中的特定列填充data
列表。接下来,我创建了一个名为WeatherLocation
的子类,它继承自WeatherData
。 WeatherLocation
有三个属性:
highs
的列表,用于存储最高温度lows
的列表dates
的列表,用于存储日期如果我们查看set_data
的{{1}}方法,我们会看到与上面的代码实现相同的逻辑。调用WeatherData
的{{1}}方法时,将传递相同的行号,并将set_dates
设置为WeatherLocation
,以便执行if语句的正确部分。代码如下所示:
fetching_dates
不幸的是,此代码的输出为True
。我做错了什么?
答案 0 :(得分:2)
问题是您的超类WeatherData
有一个data
属性WeatherLocation
继承。每次set_data
您修改相同的data
属性时。在WeatherLocation
子类(例如self.highs = self.set_highs()
)中分配值时,您只返回对data
属性的引用。
当你print(sitka.dates[0])
获取实例sitka
的{{1}}的第一个元素时,它实际上只是对dates
的引用。 sitka.dates
首先调用__init__
(并且是修改self.set_highs()
的第一件事),因此您确实打印了第一个高点。如果您data
,您应该看到相同的值(例如46)。
如果您打印完整的数据列表(print(sitka.data[0])
),您应该会看到该订单中的高点,低点和日期列表。
答案 1 :(得分:0)
由于WeatherData.set_data()
每次运行都会附加到列表self.data
,因此第一个元素sitka.dates[0]
将是set_highs()
的结果,因此它是一个整数。由于您最后致电set_dates
,因此日期将会更晚。
self.highs = self.set_highs() // append integers to self.data
self.lows = self.set_lows() // append integers to self.data
self.dates = self.set_dates() // append datetimes to self.date
您的类的设计,尤其是继承的使用非常混乱。您可能需要考虑重构和使用python属性,而不是使用getter和setter方法。