2009-03-23 2 views
3

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

>>> 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) 

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

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

ответ

8

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

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

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

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 

Notes.

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

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

  3. Функция не зависит от чего-либо еще.

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

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

+0

А, так что init/self следует использовать с классами, а не с классами defen aren'tinside? – 2009-03-23 18:28:28

+0

Или, скорее, def __init__ следует использовать в классах, а def what (self, ...) следует использовать и в классах, модули/методы сами по себе не должны иметь себя? – 2009-03-23 18:29:44

+1

Технически «я» не является ключевым словом. На практике вы должны притворяться, что это так. – Brian

0

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

0

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

2

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

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

def __output(self): 
    print self.foo 

C.output = __output 
c = C() 
c.output() 
+0

Кажется, это круглый метод. Есть ли у вас нетривиальный пример? – tgray

+0

Я могу привести много примеров, но все они сводятся к установке атрибута класса в функцию, определенную вне нее. Monkeypatching наиболее полезен, если вы не можете изменить сам класс, потому что он является частью другой библиотеки или потому, что у вас нет исходного кода. –

+0

Я вижу. Спасибо за объяснение! – tgray

1

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

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

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

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

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