Python, __init__ и путаница - PullRequest
3 голосов
/ 23 марта 2009

Хорошо, поэтому я взглянул на какой-то источник, когда наткнулся на это:

>>> def __parse(self, filename):
...         "parse ID3v1.0 tags from MP3 file"
...         self.clear()
...         try:
...             fsock = open(filename, "rb", 0)
...             try:
...                 fsock.seek(-128, 2)
...                 tagdata = fsock.read(128)
...             finally:
...                 fsock.close()
...             if tagdata[:3] == 'TAG':
...                 for tag, (start, end, parseFunc) in self.tagDataMap.items():
...                     self[tag] = parseFunc(tagdata[start:end])
...         except IOError:
...             pass
... 

Итак, я решил проверить это.

 >>> __parse("blah.mp3")

И я получил эту ошибку:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __parse() takes exactly 2 arguments (1 given)

Это не первый раз, когда я сталкиваюсь с этим, я продолжаю думать, что должен включить self в список параметров аргумента, но я знаю, что это неправильно. Может ли кто-нибудь объяснить мне, почему это часто происходит с кодом, с которым я пытаюсь поиграть, полагаю, это из-за моего уровня понимания терминов, я даже почти не понимаю, что делает init или self, или почему это важно. def x (b): print b совпадает с def x (self, b): self.b = b print self.b не так ли? Почему это так важно!

Мне просто нужно базовое объяснение, чтобы я мог выбросить это из головы, спасибо.

Ответы [ 5 ]

8 голосов
/ 23 марта 2009

def __parse было внутри некоторого определения класса.

Вы не можете извлечь метод определения из определений классов. Определение функции метода является частью класса.

Посмотрите на эти два примера:

def add( a, b ):
    return a + b

И

class Adder( object ):
    def __init__( self ):
        self.grand_total = 0
    def add( self, a, b ):
        self.grand_total += a+b
        return a+b

Примечание.

  1. Функция не использует self.

  2. Метод класса использует self. Как правило, все методы экземпляра будут использовать self, если только у них нет определенных декораторов, таких как @classmethod, которые говорят иначе.

  3. Функция не зависит ни от чего другого.

  4. Метод класса зависит от его вызова экземпляром класса Adder; кроме того, это зависит от того, правильно ли инициализирован экземпляр класса Adder. В этом случае функция инициализации (__init__) заверяет, что каждый экземпляр Adder всегда имеет переменную экземпляра с именем grand_total, а эта переменная экземпляра имеет начальное значение 0.

  5. Вы не можете извлечь функцию метода add из класса Adder и использовать ее отдельно. Это не отдельная функция. Он был определен внутри класса и имеет определенные ожидания из-за этого местоположения внутри класса.

2 голосов
/ 23 марта 2009

Функции / методы могут быть написаны вне класса и затем использоваться для техники в Python, называемой monkeypatching :

class C(object):
  def __init__(self):
    self.foo = 'bar'

def __output(self):
  print self.foo

C.output = __output
c = C()
c.output()
1 голос
/ 24 марта 2009

Похоже, вы немного запутались в классах и объектно-ориентированном программировании. «Я» - это одна из ошибок в python для людей, пришедших с других языков программирования. ИМО официальный учебник не справляется с этим слишком хорошо. Этот урок выглядит довольно хорошо.

Если вы когда-либо изучали Java, self в Python очень похож на this в Java. Разница в том, что python требует, чтобы вы указали self в качестве первого аргумента для каждой функции в определении класса.

Если python - ваш первый язык программирования (или ваш первый объектно-ориентированный язык), вы можете запомнить это как простое правило: если вы определяете функцию, которая является частью класса, вам необходимо включить self в качестве первого аргумента. Если вы определяете функцию, которая не является частью класса, вы не должны включать self в аргументы. Вы не можете взять функцию класса и сделать ее автономной без какого-либо (или, возможно, большого) дополнительного кодирования. Наконец, никогда не включайте self в качестве аргумента, когда вызывает функцию.

Есть исключения из этих правил, но о них не стоит беспокоиться.

0 голосов
/ 23 марта 2009

Кроме того, позволяет создавать статические методы класса в Python. Самый простой способ сделать это - через декораторы (например, @staticmethod). Я подозреваю, что такие вещи обычно не являются решением Pythonic.

0 голосов
/ 23 марта 2009

self автоматически передается оболочкой instancemethod для классов. Эта функция не упакована; это не метод, это просто функция. Это даже не имеет смысла без привязки к классу, так как ему нужен параметр self.

...