0

我在 Python 的类结构中创建了一个类。最后,我尝试将其属性之一 ( price) 的列表检索到sum所有值并对其进行数学运算。

它一直告诉我,我的班级TOOLBOX或班级DATA都没有属性Price。我怎么能解决这个问题?

我的代码如下所示:

class DATA:
    def __init__(self, Identifier, Price, Date, Postcode, Type, Age, Tenure, Primary, Secondary, Street, Locality, Town, District, County, Status):
        self.Identifier = Identifier
        self.Price = Price
        self.Date = Date
        self.Postcode = Postcode
        self.Type = Type
        self.Age = Age
        self.Tenure = Tenure
        self.Primary = Primary
        self.Secondary = Secondary
        self.Street = Street
        self.Locality = Locality
        self.Town = Town
        self.District = District
        self.County = County
        self.Status = Status

class TOOLBOX(object):

    def __init__ (self):
        self.alldata = []

    def add_data(self, Identifier, Price, Date, Postcode, Type, Time, Tenure, Primary, Secondary, Street, Locality, Town, District, County, Status):
        self.alldata.append(DATA(Identifier, Price, Date, Postcode, Type, Time, Tenure, Primary, Secondary, Street, Locality, Town, District, County, Status))

    def get_prize(self) :
        price=[]
        for line in self.alldata:
                price.append(self.alldata.Price)
        print price

    def summation(self):
        return sum(self.alldata.Price)



csv_ff = csv.reader(open("FINAL.csv",'rU'))
l=len(list(csv.reader(open("FINAL.csv",'rU'))))

dd = TOOLBOX()

for line in csv_ff:
    if len(line)==15:

        Identifier=line[0]
        Price=int(line[1])
        Date=line[2]
        Postcode=line[3]
        Type=line[4]
        Age=line[5]
        Tenure=line[6]
        Primary=line[7]
        Secondary=line[8]
        Street=line[9]
        Locality=line[10]
        Town=line[11]
        District=line[12]
        County=line[13]
        Status=line[14]

        dd.add_data(Identifier, Price, Date, Postcode, Type, Age, Tenure, Primary, Secondary, Street, Locality, Town, District, County, Status)
4

5 回答 5

1

PriceDATA存储在self.alldata列表中的实例的属性。因此,您需要遍历self.alldata列表并获取Price属性,如下所示:

def get_prices(self) :
    prices=[]
    for line in self.alldata:
         price.append(line.Price)
    return prices

笔记:

  1. 我将方法重命名get_prizeget_prices
  2. get_prices()现在返回价格列表,而不是仅仅打印它们。
  3. 如果get_prices()要打印价格列表,最好命名display_prices()或类似 -get_prize()建议该方法返回一个值。

然后您的求和方法可以通过调用get_prices()和求和它们来获取价格列表:

def summation(self):
    return sum(self.get_prices())
于 2015-02-06T11:28:14.417 回答
0

DATA的课程确实具有属性 - 没有 Price 属性的是 attr。alldataTOOLBOX.It 只是一个列表。

虽然在 Python 中构建一个可以以这种“jQueriest”方式运行的序列对象是可能的、简单的和有趣的 - 即:在需要序列中的属性时,为序列中的所有对象检索该属性的序列,这不是语言的默认行为 - 如果没有专门的类,doestoolbox_object.alldata.Price会尝试Price检索alldata.

要检索所有价格的序列(作为生成器表达式),您应该编写:

(elem.Price for elem in toolbox_object.alldata)

因此,您的线路是:

def summation(self):
    return sum(self.alldata.Price)

你应该有:

def summation(self):
    return sum(element.Price for element in self.alldata)

(顺便说一句,你的 DATA类也应该从“对象”继承)

现在,为了好玩,如果你想要类似 jQuery 的属性检索,你可以用一个额外的__getattr__方法从 Python 的列表中创建一个派生的 - 这应该可以工作(真正的“按书本”,“产品准备好”的东西可以用抽象基类,等等 - 但这只是工作):

class JQList(list):
     def __getattr__(self, attr):
          return [getattr(element, attr) for element in self]

>>> import random
>>> 
>>> b = JQList()
>>> b = JQList(random.randint(0,10) + random.randint(0,10) * 1j for i in range(10) )
>>> b
[(5+7j), (3+4j), 3j, (4+9j), (1+9j), (2+3j), (1+0j), (10+4j), 9j, (9+10j)]
>>> b.real
[5.0, 3.0, 0.0, 4.0, 1.0, 2.0, 1.0, 10.0, 0.0, 9.0]
>>> b.imag
[7.0, 4.0, 3.0, 9.0, 9.0, 3.0, 0.0, 4.0, 9.0, 10.0]
于 2015-02-06T11:27:12.517 回答
0

您正在尝试使用 allData 列表访问该属性:

self.alldata.Price # incorrect 

self.Price # correct

self.PriceDATA类中的属性,self.alldata是包含 DATA 实例的列表,您需要遍历列表并调用类似ele.Price的方法来访问 ele 所在的属性for ele in self.alldata:....

您基本上是在尝试对[].Price列表进行操作,列表当然没有 Price 方法,因此这将失败。

    def get_prize(self) :
        price = []
        for line in self.alldata: # stores instances of DATA
              price.append(line.Price) # access attribute using the instance
        print price

def summation(self):
    return sum(inst.Price for inst in self.alldata) # again access using instance 

如果您更改get_prize方法以返回价格列表:

     def get_prize(self) :
            price = []
            for line in self.alldata: # stores instances of DATA
                  price.append(line.Price) # access attribute using the instamce
            return  price

我们可以简单地使用该方法求和:

    def summation(self):
        return sum(self.get_prize())

我们还可以返回一个get_prize更简洁的列表推导式,并使用一个更能描述每个元素是什么的变量:

def get_prize(self) :
    return  [inst.Price for inst  in self.alldata]

在旁注中,使用小写字母和下划线表示属性等 self.price, identifier self.all_data......

于 2015-02-06T11:15:13.250 回答
0

此代码的更多提示-(有关您的问题的答案,请查看我的其他答案)

Python 是一种允许人们真正编写短而易读的代码的语言 - 在这个小例子中,您将 15 个属性的名称重复 7 次 --- 这是很多属性名称的输入 :-)

因此,无需对代码进行任何更改,如果您知道将从 csv 文件中按顺序获取属性,并且不应该更改,您只需将实例化代码更改为:

对于 csv_ff 中的行:如果 len(line)==15: dd.add_data(*line)

行序列前面的“*”将在调用 .add_data 的位置参数中“展开”它的每个元素。- 这将删除所有变量名。

你可以在add_data方法中做同样的事情 - 它可以是:

def add_data(self, *args):
    self.all_data.append(DATA(*args))

函数(/方法)定义中的“*”只是告诉 Python 获取所有剩余的位置参数,并将它们放在名为“args”的列表中。我们没有在那里使用参数,我们只是传递它们。按原样折叠到DATA对象构造函数。请注意,这还将您的 TOOLBOX 类与对象的特定属性分离。

也有一些技巧可以缩短DATA实现的方式,但是会在可读性/复杂性之间进行权衡。(虽然很小)

于 2015-02-06T11:48:57.003 回答
-1

我认为这可能是一个简单的解决方案:

class DATA:
def __init__(self,Price):   # skipped other parameters    
    self.Price = Price

class TOOLBOX(object):

def __init__ (self):
    self.alldata = []

def add_data(self, Price):
    self.alldata.append(DATA(Price))

def get_prize(self) :
    price=[]
    for line in self.alldata:
            price.append(line.Price)
    print(price)
    return price

def summation(self):
    return sum(self.get_prize())

# use example
T=TOOLBOX()
T.add_data(2)
T.add_data(3)
print(T.summation())
# 5

get_prize() 可以写得更优雅:

 def get_prize(self) :
    price = [line.Price for line in self.alldata]
    print(price)
    return price
于 2015-02-06T11:42:18.317 回答