2017-01-28 3 views
3

J'apprends Python et j'essaie de simuler un jeu de cartes. J'ai une question concernant la notation par points. J'ai regardé partout sur Internet pour une réponse spécifique, mais j'ai été incapable d'en trouver un.Notation par points en Python. La méthode devrait-elle venir avant ou après l'objet?

Pourquoi est-il, que, parfois, nous apprenons à appeler une méthode en notation point comme ceci:

object.methodName() 

Alors que d'autres fois, on nous montre l'appeler comme ceci:

className.methodName(object) 

Qu'est-ce que est la différence?

Voici un exemple spécifique. Ceci est une définition de la méthode du livre (Comment penser comme un informaticien)

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) 

Parfois, l'objet vient avant la méthode:

self.isEmpty() 

Parfois, l'objet vient après la méthode, dans la parenthèse :

Deck.__str__(self) 

Quelle méthode utilisons-nous? Est-ce que ça importe?

+2

'Deck' est une * classe *, et' Deck .__ str__' est une méthode non liée. Si vous avez essayé 'self .__ str __()' à la place, vous appelleriez à nouveau la méthode 'Hand .__ str __()' (provoquant une erreur de récursion infinie), vous voulez la classe parent, donc elle est appelée explicitement. –

+2

Cependant, appeler la classe comme ça n'est pas recommandé. Utilisez 'super() .__ str __()' à la place (et laissez 'super()' comprendre ce qu'est la classe parente et comment trouver 'Deck .__ str__' à' self' correctement). –

+1

Vous avez remplacé la méthode '__str__' dans la sous-classe' Hand', ce qui est nécessaire pour appeler la version parente de '__str__'. Comme mentionné, vous devriez faire 'super() .__ str __()' à la place car il traite des structures d'héritage plus compliquées. – tdelaney

Répondre

1

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

Deck.__str__(self) 

Non, l'objet vient toujours avant sa propre méthode. Il y a deux "objets" python dans cette ligne. Vous passez l'objet self (qui est vraiment une instance de classe) en tant que paramètre à la méthode __str__ de l'objet Deck (qui est vraiment une classe).

1

Wenn que vous utilisez:

object.methodName() 

vous appelez la méthode d'une instance spéciale avec ses propres données. Comme la méthode est liée à l'instance donnée, vous obtenez des résultats différents.

a = Hand() 
b = Hand() 

puis

a.cards 
b.cards 

peuvent être différents (dans la plupart des cas).

Pour accéder à ces données, l'objet doit mettre toutes les méthodes. Cela se fait par:

def foo(self): 
    return self.cards 

Lorsque vous définissez la méthode. À moins que vous n'écriviez une méthode de classe spéciale que vous devez toujours mettre le soi là-bas.

Lorsque vous appelez object.methodName(), la méthode obtient automatiquement les informations de l'objet auquel elle appartient (car vous transmettez la référence d'objet/instance avant le point.) Cette information est stockée dans le paramètre self.Ainsi, la boîte méthode par exemple faire: return self.cards

Mais si vous l'appelez comme Deck.__str__(self) que vous avez seulement la classe, cela signifie qu'il n'y a pas self (qui est la référence de l'objet lui-même).

Ainsi, la méthode ne sait pas à quelles données d'instance elle appartient, vous devez donc passer le self. Ainsi, si vous appelez: object.__str__(), les informations sur l'instance sont fournies car vous avez utilisé la référence d'objet pour appeler la méthode.

Mais si vous utilisez Deck resp. le className que vous devez mettre les informations sur l'instance également via className.method(self) car sinon il n'y a pas de référence d'objet pour une instance d'objet.

J'espère que cette explication est compréhensible.

0

Généralement, l'objet vient en premier.

Comme ceci:

object.methodName()

Ou comme ceci:

self.isEmpty()

Mais je voulais savoir pourquoi mon livre Python me apprend à appeler ce une méthode comme ceci:

Deck.__str__(self)

Je voulais savoir pourquoi "self" est entre parenthèses à la fin, et non au début de la méthode. Autrement dit, pourquoi ne pas l'écrire comme ceci:

self.Deck._str_()

La raison est que le code ci-dessus renvoie une erreur:

"Hand instance has no attribute Deck

L'erreur ci-dessus est dû au fait que par écrit cette façon, Python pense que "Deck" est un attribut de soi. Mais dans ce cas, ce n'est pas le cas. Deck, est le type PARENT au type Hand, ce n'est pas un attribut de self.

Voici le bloc de code dans lequel vous pouvez voir le code en question, ainsi que le type parent (Deck) et le type d'enfant avec lequel je travaille (Hand). Dans ce code, nous écrivons une méthode pour écraser la mise en forme des chaînes pour Hand, en accédant à la mise en forme des chaînes dans Deck. L'extrait de code Deck.__str__(self) s'écrit de cette façon car nous avons besoin d'un moyen de dire à Python quel type d'objet nous voulons copier de la mise en forme de la chaîne. Dans ce cas, nous voulions la mise en forme de chaîne à partir de Deck, le parent.

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) 

En outre, comme indiqué par @ Martijn Pieters, en utilisant SUPER: super().__str__() est mieux que de le faire comme je l'ai fait: Deck.__str__(self) Nous avons pas encore appris super, mais vous pouvez en savoir plus sur ici (https://docs.python.org/2/library/functions.html#super).Super dit en gros à Python de trouver le formatage parent pour vous, et l'utilise. Beaucoup plus facile!

J'espère que cette explication est compréhensible. J'ai essayé de surexpliquer pour compenser tout ce qui n'est pas clair: -/