2015-02-06 4 views
0

Я создал класс внутри структуры класса в Python. В конце я пытаюсь получить список одного из его атрибутов (price) до sum всех значений и выполнять с ним математические операции.Доступ к атрибутам и перечисление в классе Python

Он продолжает говорить мне, что ни мой класс 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) 
+2

Не должно быть 'price.append (line.Price)'? – jonrsharpe

ответ

0

Вы пытаетесь получить доступ к атрибуту, используя вам список ALLDATA:

self.alldata.Price # incorrect 

self.Price # correct 

self.Price является атрибутом из DATA класса, self.alldata список содержащие экземпляры DATA, вам нужно будет перебирать список и называть что-то вроде ele.Price для доступа к атрибуту, в котором находится элемент: for ele in self.alldata: ....

Вы в основном пытаетесь сделать [].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 ...

+0

Большое спасибо вам обоим. Я застрял на нем почти целый день, и теперь он работает :). Я только начал программировать, и это может быть немного концептуальным недостатком, но почему мой класс DATA не показывает все атрибуты, которые я определил, когда я делаю dir (DATA)?. Я просто получаю это: >>> dir (DATA) ['__doc__', '__init__', '__module__'] –

+0

Вы имеете в виду 'dr = DATA (1,1,1,1,1,1,1, 11,1,1,11,1,1,1,1) печать (реж (др)) '? Сначала необходимо создать экземпляр –

0

Вы класс DATA имеет атрибут - то, что не имеет атрибут Цена является атр. alldata от TOOLBOX. Это всего лишь список.

Хотя в Python было бы возможно, легко и весело создавать объект последовательности, который мог бы вести себя в этом «jQueriest» способе - то есть: при желании атрибута из последовательности извлекать последовательность этих атрибутов для всех объекты в последовательности, которые не являются поведением по умолчанию для языка - Без специальных классов выполнение toolbox_object.alldata.Price пытается получить атрибут Pricealldata.

Чтобы получить последовательность всех цен (как выражение генератора), вы должны написать:

(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-like, вы можете создать производный от списков Python с помощью только дополнительного метода __getattr__ - который должен работать (действительно «по книге», «готовый продукт», вещь может быть реализована с абстрактными базовыми классами, и так далее - но это просто работает):

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] 
1

Price является атрибутом объявления из DATA экземпляров, хранящихся в self.alldata в списке. Следовательно, вам нужно перебрать self.alldata списка и захватить атрибут Price так:

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

Примечания:

  1. Я переименовал метод из get_prize в get_prices
  2. get_prices() теперь возвращает список а не только .
  3. Если get_prices() является печать список цен было бы лучше назвали display_prices() или аналогичный - get_prize() предполагает, что метод возвращает значение.

Тогда ваш метод суммирования можно получить список цен по телефону get_prices() и просуммировать их:

def summation(self): 
    return sum(self.get_prices()) 
-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 
0

Дополнительные советы к этому коду - (для ответа на вашу проблему, проверьте мой другой ответ)

Python это язык, который позволяет действительно писать короткие и читаемый код - В этом небольшом примере, вы повторяя имя из 15 атрибутов в 7 раз - --- много имени атрибута :-)

Итак, без каких-либо изменений в коде, если вы знаете, что получите атрибуты в порядке от csv файл, и он не должен изменяться, вы можете просто изменить код создания:

для строки в csv_ff: if len (строка) == 15: dd.add_data (* line)

То, что «*», добавив последовательность строк, «разворачивает» каждый из своих элементов в позиционном аргументе для вызова .add_data. - это приведет к удалению всех имен переменных.

Вы могли бы сделать то же самое в методе add_data - это может быть этого нужно просто:

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

Определение «*» в функции (/) метод просто говорит Python принять все остальные позиционные аргументы, и поставить их в списке с именем «args». Мы не используем там argumetns, мы просто передаем их. сложенными, как они есть, в конструктор объекта DATA. Обратите внимание, что это также отделяет ваш класс TOOLBOX от определенных атрибутов для ваших объектов.

Есть также уловки, которые также сокращают путь DATA, но будет компромисс с удобочитаемостью/сложностью. (хотя и небольшой)