2015-07-02 1 views
1

Я пытаюсь загрузить данные из текстовых файлов в объекты python класса. Однако, когда я запускаю код, каждый объект получает все данные, загруженные из предыдущих текстовых файлов, загружаемых в его атрибуты, и я не знаю, как это происходит. Я был бы очень благодарен за помощь, спасибо.объекты python, берущие атрибуты предыдущих объектов из неправильных текстовых файлов, а также их собственные из правильных текстовых файлов

class Cocktail: 

    recipe = [] 
    categories = [] 
    line = '' 
    line2 = '' 
    character = [] 
    name = '' 
    path = '' 

    def __init__(self): 
     cocktails.append(self) 
     #self.name = name 

    def define(self, name): 
     #print(self.name) 
     self.name = name #the name of the cocktail is taken from a master text file 
     self.path = self.name + '.txt' #each object will be linked to an individual text file containing its data 
     with open(self.path, 'r') as cocktail_data: #opening the specific text file 
      for line in cocktail_data: 
       self.character = line.split(' ', 1) 
       if self.character[0] == '#': #if the line starts with a # 
        self.line = line.strip('#') 
        self.line2 = self.line.strip('/n') 
        self.categories.append(self.line2) #loads that lines data into the objects 'categories list' 

       elif line.strip() == 'recipe': #when the recipe part of the text file is reached 
        break 
      for line in cocktail_data: #continuing through the document 
       self.recipe.append(line.strip()) #adds each line of the rest of the document to the object's 'recipe' attribute 

    def print(self): #for testing 
     print(self.name) #prints the name of that cocktail that the object represents 
     print(self.categories) #prints all the categories for that object 
     print(self.recipe) #prints the recipe list for that object 
     print('end') 
     #each new object seems to have the values (for its categories and recipe attributes) for all previous objects as well as its own 
cocktails = [] 

with open('master.txt') as input_data: 
    for line in input_data: 
     name = line.strip() #the string that is the current line on the master text file 
     cocktail = Cocktail() #creates object of Cocktail for each name in master document 
     cocktail.define(name) 
     cocktail.print() 

Это то, что мои питона оболочки показывает:

cocktail1 

[' a\n', ' b\n', ' c\n', ' d\n'] 

['one', 'two', 'three', 'end'] 

end 

cocktail2 

[' a\n', ' b\n', ' c\n', ' d\n', ' aq\n', ' bq\n', ' cq\n', ' dq\n'] 

['one', 'two', 'three', 'end', 'one q', 'two q', 'threeq', 'endq'] 

end 

cocktail3 

[' a\n', ' b\n', ' c\n', ' d\n', ' aq\n', ' bq\n', ' cq\n', ' dq\n', ' aw\n', ' bw\n', ' cw\n', ' dw\n'] 

['one', 'two', 'three', 'end', 'one q', 'two q', 'threeq', 'endq', 'onew', 'two w', 'threew', 'endw'] 

end 

cocktail1 не должны иметь с «д» или «W» в конце концов, коктейль 2 должны иметь только те, с микросхемой «q» в конце и коктейль 3 должны иметь только те, у которых «w» в конце

ответ

1

Возможно, вы используете Java или другие языки OO, где атрибуты экземпляра объявлены в теле класса, и вы пытаясь сделать то же самое здесь:

class Cocktail: 

    recipe = [] 
    categories = [] 
    line = '' 
    line2 = '' 
    character = [] 
    name = '' 
    path = '' 

    def __init__(self): 
     cocktails.append(self) 
     #self.name = name 

В Python, однако, любое объявление в корпусе класса, если для атрибута класса. Атрибуты экземпляра устанавливаются непосредственно в экземпляре (внутри методов с использованием оператора типа self.attrname = value)

Для некоторых из приведенных выше атрибутов вы не увидите проблемы, так как вы используете неизменяемые объекты и просто затеняете атрибуты класса, когда вы установите их в экземпляре - например, когда вы делаете self.name = name - вы создаете новый атрибут name только для этого экземпляра.

Однако, если вы делаете self.categories.append(...), вы изменяете объект categories (список), который определен в классе коктейлей, и к нему обращаются все объекты коктейлей.

Чтобы исправить свое поведение, просто объявить экземпляр атрибуты как таковой - это делает, например:

class Cocktail: 
    def __init__(self): 
     self.recipe = [] 
     self.categories = [] 
     self.line = '' 
     self.line2 = '' 
     self.character = [] 
     self.name = '' 
     self.path = '' 

(но имейте в виду, вы не должны объявлять переменную или атрибут в Python перед вами нужно установить его значение во время выполнения - вы можете просто установить их в нужные вам методы - единственные, которые вам нужны для создания, - это те, которые содержат списки, поскольку вы хотите добавить к ним значения).

Смежные вопросы