Как разделить () строку и передать ее в метод __init __ () объекта? - PullRequest
0 голосов
/ 14 мая 2018

Я пытаюсь создать несколько экземпляров объекта 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

Здесь я сталкиваюсь с проблемами.Self IIRC стоит вместо строки в основном коде, поэтому self должно быть строкой, такой как "Mtn. Dew, 1.00,10", и ожидаемый результат метода split (",") должен формировать список, подобный ["Mtn. Dew "," 1.00 "," 10 "], где я могу затем использовать индекс этого списка, чтобы вернуть только имя.

Однако я получаю эту ошибку" AttributeError: Экземпляр Soda не имеет атрибута 'split«И я не знаю почему.Кроме того, все комментарии в этом коде были получены от моего инструктора как часть задания, так что даже если есть более быстрые / лучшие методы для выполнения всего этого, я так и сделаю: /

Ответы [ 5 ]

0 голосов
/ 14 мая 2018

Нет места, которое вы фактически передаете в строке либо getName, либо __init__. Вызов self.getName() не передается ни в одной строке.

В этом случае init будет ожидать (имя, цена, номер), а не строка. Таким образом, Pythonic должен добавить статический метод from_string/make/make_from_string:

class Soda:
    def __init__(self, name = '', price = 0.0, quantity = 0) :
            self._name = name
            self._price = price
            self._quantity = quantity

    @staticmethod
    def from_string(s):
        return Soda(s.split(','))


 >>> Soda.from_string('Mtn. Dew,1.00,10')
 <__main__.Soda object at 0x107428f60>
 # Success! Mind you, your class could do with a __str__() method now...
0 голосов
/ 14 мая 2018

IIRC self стоит на месте строки в основном коде, поэтому self должно быть строка, такая как «Mtn. Dew, 1.00,10» и ожидаемый результат Метод split (",") должен формировать список вроде ["Mtn. Dew", "1.00", "10"] где я могу затем использовать индекс этого списка, чтобы вернуть только имя.

Подожди минутку. Это распространенное заблуждение, когда люди учатся кодировать. По сути, вы путаете исходный код с типом данных str. Это простая ошибка, так как каждый создает текстовый файл, когда пишет исходный код. Один пишет текст в файл, а другой может даже загрузить его в Python (open('my_script.py').read()), и мы получим строку! И да, строки потребляются программами, которые вы запускаете, когда ваш исходный код переходит от вашего языка программирования к машинному коду Но я выступаю за то, чтобы вы держали эти две вещи в своем разуме отдельно. Ваш исходный код не является строкой . Он должен концептуально находиться «над» этим (и в любом случае, здесь мы имеем дело с полезными абстракциями). Итак, пока ваша идея по существу верна,

self стоит на месте строки в основном коде

Но здесь «строка» означает, что строка относится к , фрагменту логики, выполняемой вашим кодом, а не буквально строке кода, которую вы пишете. Так, self относится к объекту instance , когда метод выполняется экземпляром класса.

Итак, self - это , а не строка . Это объект того типа, который определяет ваш класс. У вашего класса нет этого метода. str объекты делают.

Вот небольшой взгляд на модель данных Python. «Я» довольно просто. Сам экземпляр передается в качестве аргумента. Это делается под прикрытием для вас «магией» (магией, с которой вы можете научиться играть позже), но по существу, 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

Но, пожалуйста, придерживайтесь соглашения.

0 голосов
/ 14 мая 2018

Когда вы используете self, вы ссылаетесь на экземпляр Soda, и, поскольку вы не определили метод разбиения, он не будет иметь его.

Вы можете просто использовать распаковку, чтобы передать результат split в класс.

Возможно, вы захотите добавить в некоторые проверки, чтобы убедиться, что распаковка возвращает три значения, хотя, поскольку вы используете аргументы по умолчанию, она выдаст ошибку, только если вы укажете больше , чем три значения.

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)
0 голосов
/ 14 мая 2018

В классе Soda ключевое слово «self» относится к экземпляру Soda.Просто «разделить» объект Soda здесь не имеет особого смысла.На самом деле вы хотите разделить строковые аргументы при создании каждого объекта Soda.

Следовательно, лучший способ - разделить аргументы по имени, цене и количеству в init () function.

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 ~

0 голосов
/ 14 мая 2018

Переменная 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 по соглашению.

...