2017-01-28 21 views
3

Я изучаю Python, и я пытаюсь имитировать карточную игру. У меня есть вопрос относительно точка нотация. Я просмотрел по всему Интернету конкретный ответ, но не смог его найти.Точечная запись в Python. Должен ли метод проходить до или после объекта?

Почему это, что иногда нас учат вызывать метод точечной нотации, как это:

object.methodName() 

В то время как другие времена, мы показали, называть это так:

className.methodName(object) 

Что это разница?

Вот пример. Это определение метода из книги (Как думать, как ученый)

class Hand(Deck): 
    def __init__ (self, name = " "): 
     self.cards = [] 
     self.name = name 

    def __str__(self): 
     s = "Hand "+ self.name 
     if self.isEmpty(): 
      return s+" is empty\n" 
     else: 
      return s+ " contains\n" + Deck.__str__(self) 

Иногда объект предшествует метод:

self.isEmpty() 

Иногда объект приходит после того, как метода, в круглых скобках :

Deck.__str__(self) 

Какой метод мы используем? Это имеет значение?

+2

'Deck' - это * класс *, а' Deck .__ str__' - это несвязанный метод. Если вы попробуете 'self .__ str __()' вместо этого, вы снова вызовете метод 'Hand .__ str __()' (вызывая бесконечную ошибку рекурсии), вы хотите родительский класс, поэтому он вызывается явно. –

+2

Однако вызов такого класса не рекомендуется. Вместо этого используйте 'super() .__ str __()' (и пусть 'super()' определяет, что такое родительский класс, и как правильно найти 'Deck .__ str__'' 'self'. –

+1

Вы перепробовали метод '__str__' в подклассе' Hand', поэтому это необходимо для вызова родительской версии '__str__'. Как уже упоминалось, вы должны сделать 'super() .__ str __()' вместо этого, поскольку он имеет дело с более сложными структурами наследования. – tdelaney

ответ

1

Sometimes the object comes after the method, in the parenthesis:

Deck.__str__(self) 

Нет, объект всегда предшествует его собственный метод. В этой строке есть два «объекта» python. Вы передаете объект self (который действительно является экземпляром класса) в качестве параметра для метода __str__ объекта Deck (который действительно является классом).

1

Венна вы используете:

object.methodName() 

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

a = Hand() 
b = Hand() 

затем

a.cards 
b.cards 

может быть различным (в большинстве случаев).

Для доступа к этим данным объект self должен быть помещен в каждый метод. Это делается:

def foo(self): 
    return self.cards 

При определении метода.

Если вы не пишете специальный метод класса, который вам всегда нужно поставить сам.

При вызове object.methodName() метод автоматически получает информацию об объекте, которому он принадлежит (поскольку вы передаете ссылку объекта/экземпляра перед точкой. Эта информация хранится в параметре self.Таким образом, способ может, например, сделать: return self.cards

Но если вы называете это как Deck.__str__(self), чем у вас есть только класс это означает, что нет self (который сам по себе ссылка на объект).

Таким образом, метод не знает, какие данные экземпляра он принадлежит, поэтому вам необходимо передать self.

Итак, если вы звоните: object.__str__() информация о экземпляре дается, потому что вы использовали ссылку на объект для вызова метода.

Но если вы используете Deck resp. className, чем вы должны поместить информацию об экземпляре также через className.method(self), потому что в противном случае ссылка на объект для экземпляра объекта отсутствует.

Я надеюсь, что это объяснение понятно.

0

Как правило, объект на первом месте.

Как это:

object.methodName()

Или так:

self.isEmpty()

Но я хотел бы знать, почему моя книга Python учит меня назвать это один из способов, как это:

Deck.__str__(self)

Я хотел знать, почему «я» находится в круглых скобках в конце, а не в начале метода. Другими словами, почему бы не написать это так:

self.Deck._str_()

причины, в том, что приведенный выше код будет выдавать ошибку:

"Hand instance has no attribute Deck

вызывается выше ошибка, потому что написано это Кстати, Python считает, что «Палуба» является атрибутом «я». Но в этом случае это не так. Deck, является типом PARENT для типа Hand, это не атрибут self.

Вот блок кода, где вы можете увидеть код, о котором идет речь, а также тип родителя (Deck) и тип дочернего элемента, с которым я работаю (Hand). В этом коде мы пишем метод для перезаписи форматирования строк для Hand, путем обращения к форматированию строк в Deck. Этот фрагмент кода Deck.__str__(self) написан таким образом, потому что нам нужен способ рассказать Python, который тип объекта мы хотели бы скопировать форматирование строки. В этом случае нам понадобилось форматирование строки из Deck, родительского.

class Hand(Deck): def __init__ (self, name = " "): self.cards = [] self.name = name

def __str__(self): 
    s = "Hand "+ self.name 
    if self.isEmpty(): 
     return s+" is empty\n" 
    else: 
     return s+ " contains\n" + Deck.__str__(self) 

Кроме того, как заявил @ Мартейн Питерс, используя SUPER: super().__str__() лучше, чем делать это так, как я сделал: Deck.__str__(self) Мы еще не научились Супер, но вы можете узнать больше о это здесь (https://docs.python.org/2/library/functions.html#super).Super в основном говорит Python, чтобы найти родительское форматирование для вас и использовать его. Намного легче!

Я надеюсь, что это объяснение понятно. Я попытался чрезмерно объяснить, чтобы компенсировать все, что неясно: -/