2011-12-28 2 views
2

Я новичок в Python. Я не понимаю, как/почему используется self аргумент:использование аргумента self

class Person: 
    def __init__(self, name): 
     self.name = name 
    def sayHi(self): 
     print 'Hello, my name is', self.name 

p = Person('Swaroop') 
p.sayHi() 

Этот код из байт в Python. Этот код можно было бы так же легко написать, как:

def sayHi(self, name): 
      print 'Hello, my name is', name 

p = Person('Swaroop') 
p.sayHi() 

... правый? Какова цель создания name поля self?

+2

Вы пытались выполнить свой второй фрагмент? Само по себе? – quamrana

+1

Определяет, что ваш второй фрагмент кода имеет неправильный отступ. –

+1

Я не думаю, что это действительно вопрос о «себе», это вопрос о ООП и классах. –

ответ

6

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

Рассмотрим Ваш пример

class Person: 
    def __init__(self, name): 
     self.name = name 
    def sayHi(self): 
     print 'Hello, my name is', self.name 

Каждый экземпляр этого человека (Том, ​​Дик, Гарри) уникален и в каждом случае, чтобы вернуться к себе нам нужно некоторое идиомы, как (я в Python, это PTR это C++ или это в Java).

Таким образом, в методе __init__, когда вам нужно разграничить между атрибутом name лица с параметром name мы можем легко сделать это с self. Не только это, в любом случае, мы можем продолжать ссылаться на это имя через self.

Создание экземпляра Person p=Person('Swaroop') и затем, вызывая SayHi контрастным называть просто функцию SayHi которая не является частью объекта имеет два значения

  1. Функция преходяща, не имеет никакого состояния, нет экземпляра и это похоже на «Говорить этому парню». Эй, мистер, который когда-либо говорил «Привет, меня зовут Свароп». Это похоже на каждый ход, который вы должны сделать, чтобы глупость осознала его имя, которое забудет в следующий момент, когда вы встретитесь с ним. Это похоже на то, что Гай страдает от Anterograde_amnesia. Вызов sayHi экземпляра Person с именем Swaroop с другой стороны означал бы что-то вроде физически существующего Swaroop-приветствия обратно его Имя, у которого есть постоянная память, и никогда не забудет, если он не примет новое имя.
  2. Функция никогда не запоминается, но забывает каждый раз, когда вызов заканчивается. Объект Person будет помнить имя до тех пор, пока вы явно или неявно не убьете этого человека.

Если у вас есть фон C++ и может быть интересно, почему на земле нам нужно добавить этот дополнительный параметр в вызов функции, где, как и в C++, этот указатель никогда не передается. Хорошо, Кандидат говорит. Если вы читаете соглашение о вызове C++, будь то X86 или X64, этот указатель передается через регистр ecx методу, чтобы дать дескриптор самому себе. Здесь яснее здесь, где мы намеренно передаем дескриптор текущему экземпляру методу.

4

Посмотрите на новый метод sayHiTo:

class Person: 
    def __init__(self, name): 
     self.name = name 
    def sayHi(self): 
     print 'Hello, my name is', self.name 
    def sayHiTo(self, other): 
     print 'Hello', other.name, ' my name is', self.name 

p1 = Person('Swaroop') 
p2 = Person('codeninja') 
p1.sayHiTo(p2) 
p2.sayHiTo(p1) 
+1

Очень хорошая точка. Это отличная причина иметь атрибуты участника. Теперь вам даже не нужно знать их имена, чтобы сказать привет друг другу, поскольку каждый экземпляр несет свою ценность и знает, как сказать hi между экземплярами класса Person. – jdi

0

Целью является сохранить ссылку на имя, чтобы вы могли ссылаться на нее в другом методе класса, например def sayHi (self)

2

Фактически нет. Ваш второй пример неверен. Ключевое слово 'self' - это специальная ссылка, которая передается методам экземпляра класса. Он представляет фактический экземпляр класса в этой области. Когда вы создаете класс, это просто общее определение. Затем вы создаете экземпляры этого класса. Каждый экземпляр уникален, и поэтому методы должны иметь возможность работать с этим экземпляром. У вас нет способа узнать их, пока они не будут сделаны так, чтобы «я» передал их вам.

Например, если вы создали два экземпляра вашего лица класса:

p1 = Person("john") 
p2 = Person("sam") 

значение self.name отличается для каждого из них. И когда вы вызываете sayHi() в каждом случае:

p1.sayHi() 
> Hello, my name is john 
p2. sayHi() 
> Hello, my name is sam 

Вы не использовали бы ключевое слово self для несвязанных функций. То есть, просто общие функции, как то, что вы написали в качестве второго примера. Вместо этого вы должны написать это так:

def sayHi(name): 
     print 'Hello, my name is', name 

    p = Person('Swaroop') 
    p.sayHi() 

> sayHi("john") 

Но это в основном просто передало строку имени классу Person и вызывало его метод. Идея здесь заключается в том, что вы создаете уникальные экземпляры Person со своими собственными свойствами.

+1

У Сэма есть плохая грамматика. ;) –

+1

Бедный сэм пошел в колледж :-) Исправлена ​​благодарность – jdi

0

Вы не можете сравнить функцию в классе только с функцией. Конечно, вы можете передать имя, но идея использования класса заключается в том, что вы инкапсулируете данные. Имея vars, связанные с self, вы можете обойти объект, и этот объект всегда может иметь доступ к его «переменным-членам». Некоторый другой класс может использовать экземпляр Человека и не должен знать, что имя человека, чтобы сказать привет.

+0

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

+0

@ ChrisLutz - Я на самом деле предположил, что он просто выполнял несвязанную функцию, так как, если он спрашивает о ключе «я», он, скорее всего, не в курсе обучения classmethod – jdi

+0

@jdi - я понял, что «classmethod» означает что-то другое, и Исправлена ​​моя формулировка. Я думаю, что 'sayHi' должен быть частью класса и плохо отступом, потому что он называет его как' p.sayHi() ', а не' sayHi (p) '. –

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