我正在尝试使用文件中的信息创建Soda对象的多个实例。该文件的格式如下,名称,价格,数字
Mtn. Dew,1.00,10
Coke,1.50,8
Sprite,2.00,3
我的代码是这个(这是main()中的一个函数):
from Sodas import Soda
def fillMachine(filename) :
# Create an empty list that will store pop machine data
popMachine = []
# Open the file specified by filename for reading
infile = open(filename, "r")
# Loop to read each line from the file and append a new Soda object
# based upon information from the line into the pop machine list.
for line in infile :
popMachine.append(Soda(str(line.strip())))
# Close the file
infile.close()
# Return the pop machine list
return popMachine
如果我说得对,popMachine应该是3个不同Soda对象的列表,每个对象都有一行输入文件。
在我的班级中,我需要能够获得稍后用于计算的名称,价格或数量。我的类Sodas代码如下所示:
#Constructor
def __init__(self, _name = "", _price = 0.0, _quantity = 0) :
self._name = self.getName()
self._price = _price
self._quantity = _quantity
def getName(self) :
tempList = self.split(",")
self._name = tempList[0]
return self._name
这是我遇到问题的地方。 IIRC self代替主代码中的行,所以self应该是一个字符串,例如" Mtn。露,1.00,10"并且分裂(",")方法的预期结果应该形成像[" Mtn。露"," 1.00"," 10"]然后,我可以使用该列表的索引返回名称。
但是,我收到此错误"属性错误:Soda实例没有属性' split'"而且我不确定为什么。此外,此代码中的所有注释都来自我的教师作为任务的一部分,所以即使有更快/更好的方法来完成这一切,这是我必须这样做的方式:/
答案 0 :(得分:1)
self
变量引用对象实例。你可以做的是 分割构造函数中的行,如此
def __init__(self, line):
name, price, quantity = line.split(',')
self.name = name
self.price = price
self.quantity = quantity
...或者你可以在被要求时懒得分开它
def __init__(self, line):
self._name = None
self.line = line
@property
def name(self):
if self._name is None:
self._name = self.line.split()[0]
return self._name
请注意,在函数名称等python变量中,按惯例通常为snake_case
。
答案 1 :(得分:1)
当您使用self
时,您会引用Soda
的实例,并且由于您尚未定义拆分方法,因此它不会有一个。
您只需使用解包即可将split
的结果传递给班级。
您可能希望添加一些检查以确保解包返回三个值,但是因为您使用默认参数,所以只有在提供 more 而不是三个值时才会出错。
class Soda:
def __init__(self, name = "", price = 0.0, quantity = 0) :
self.name = name
self.price = price
self.quantity = quantity
sodas = []
with open('test.txt') as f:
for line in f:
sodas.append(Soda(*line.split(',')))
for soda in sodas:
print(soda.name)
输出:
Mtn. Dew
Coke
Sprite
您甚至可以定义一个帮助方法,该方法从文件中的一行返回Soda
实例:
@staticmethod
def make_soda(line):
try:
name, price, quantity = line.split(',')
return Soda(name, price, quantity)
except:
raise ValueError('Bad Soda')
您可以使用以下方式致电:
Soda.make_soda(line)
答案 2 :(得分:1)
IIRC self代替主代码中的行,所以自我应该是 一个字符串,如" Mtn。露,1.00,10"和预期的结果 split(",")方法应该形成一个像[" Mtn。露"," 1.00"," 10"] 然后,我可以使用该列表的索引返回名称。
坚持一分钟。当人们学习编码时,这是一种常见的误解。从根本上说,您将源代码与数据类型str
混为一谈。这是一个容易犯的错误,实际上,当编写源代码时,会创建一个文本文件。一个人将文本写入文件,甚至可以在Python中加载open('my_script.py').read())
,我们得到一个字符串!是的,当您的源代码从您的编程语言到达之旅时,您运行的程序会使用字符串。机器代码。但我提倡你把这两件事分开。你的源代码不是一个字符串。它应该在概念上位于"上面#(无论如何,我们在这里处理有用的抽象)。所以,虽然你的想法基本上是正确的,
self代替主代码中的行
但是这里"线"表示行引用的行,代码执行的逻辑片段,而不是您编写的代码行。因此,self
在方法由类的实例执行时引用对象 instance 。
因此,self
不是字符串。它是您的类定义的类型的对象。你的班级没有这种方法。 str
个对象可以。
在这里看一下python数据模型。 "自"非常直截了当。实例本身作为参数传递。这是通过" magic"为您完成的。 (你可以学习以后玩的魔法)但基本上,my_instance.some_method()
大致相当于到MyClass.some_method(my_instance)
考虑一下,
In [1]: class SomeClass:
...: def __init__(self, name):
...: self.name = name
...: def foo(self):
...: print(self.name, 'says foo!')
...:
In [2]: some_instance = SomeClass('Juan')
In [3]: some_instance.foo()
Juan says foo!
In [4]: SomeClass.foo(some_instance)
Juan says foo!
方法只是一个属于类的一部分的函数,如果它被该类的实例调用,它将自动神奇地将实例本身传递为第一个论点。注意,这里是特权的参数的位置,而不是名称 self ,这仅仅是约定。它可以是你想要的任何东西。名称甚至不必在类中一致(但当然,在函数本身内是一致的)。我们称之为西葫芦,以获得乐趣:
In [8]: class WhyNot:
...:
...: def __init__(self):
...: self.foo_flag = False
...: self.bar_flag = False
...:
...: def foo(zucchini):
...: print("I speak American English")
...: zucchini.foo_flag = True
...:
...: def bar(courgette):
...: print("And British English")
...: courgette.bar_flag = True
...:
In [9]: x = WhyNot()
In [10]: x.foo()
I speak American English
In [11]: x.bar()
And British English
In [12]: x.foo_flag
Out[12]: True
In [13]: x.bar_flag
Out[13]: True
但是请坚持惯例。
答案 3 :(得分:0)
在苏打课程中,关键词是“自我”。是指苏打的一个实例。简单地分开'苏打水对象在这里没有多大意义。你想要做的是在创建每个Soda对象时拆分字符串参数。
因此,更好的方法是在 init ()函数中将参数拆分为名称,价格和数量。
def __init__(self, args = "", _price = 0.0, _quantity = 0):
args = args.split(",")
self._name = args[0]
self._price = args[1]
self._quantity = args[2]
在getName函数中,顾名思义,最好只获取名称。
def getName(self) :
return self._name
我希望这可以帮助你学习Python〜
答案 4 :(得分:0)
您实际上没有将字符串传递给ssh
或getName
的地方。调用__init__
不会传入任何字符串。
这是 init 期望(名称,价格,数字)而非字符串的情况。所以Pythonic就是添加一个静态方法self.getName()
:
from_string/make/make_from_string