2016-10-01 2 views
1

J'étais sous l'impression que les méthodes dans les classes Python toujours nécessitent l'argument self (je sais que cela ne doit pas nécessairement être self, juste un mot-clé). Mais, cette classe que j'ai écrit ne l'exige pas:Pourquoi `self` n'est-il pas utilisé dans cette méthode?

import ZipFile 
import os 
class Zipper: 
    def make_archive(dir_to_zip): 
     zf = zipfile.ZipFile(dir_to_zip + '.zip', 'w') 
     for filename in files: 
      zf.write(os.path.join(dirname, filename)) 
     zf.close() 

Voir? No self. Lorsque j'inclut un argument self à make_archive, j'obtiens une erreur TypeError: make_archive() missing one positional argument. Dans ma recherche pour savoir pourquoi cela se passe, en fait je copiais et ai essayé d'exécuter un programme similaire de la documentation:

class MyClass: 
    """A simple example class""" 
    i = 12345 

    def f(self): 
     return 'hello world' 

print(MyClass.f()) # I added this statement to have a call line 

et je reçois la même erreur!

TypeError: f() missing 1 required positional argument: 'self' 

Dans le même module qui contient la classe Zipper(), j'ai plusieurs classes qui utilisent tous self. Je ne comprends pas la théorie ici, ce qui rend difficile de savoir quand faire quoi, d'autant plus qu'un programme copié directement à partir des docs (this is the docs page) a échoué quand je l'ai exécuté. J'utilise Python 3.5 et 3.4 sur Debian Linux. La seule chose que je peux penser est que c'est une méthode statique (et le Zipper.make_archive() comme écrit ci-dessus fonctionne très bien si vous incluez @staticmethod ci-dessus la méthode make_archive), mais je ne peux pas trouver une bonne explication pour être sûr.

+1

"Je ne comprends pas la théorie ici, ce qui rend difficile de savoir quand faire quoi, d'autant plus qu'un programme copié directement à partir de la docs (c'est la page docs) a échoué quand je l'ai exécuté." La partie qui a échoué n'est pas la partie que vous avez copiée des documents. L'extrait de code * très prochain * dans cette section illustre "l'instanciation" de la classe. Les deux prochaines sections couvrent les attributs (y compris les méthodes) de l'instance, etc. Vous ** devez ** lire ** et comprendre ** le texte entre les extraits de code, et pas seulement tester le code. –

+0

En outre, votre terminologie est partout.Si vous essayez de vous apprendre la langue à partir de la documentation, sachez que cela peut être difficile. En tout cas, soyez plus prudent avec ceci; la programmation exige de la précision. StackOverflow n'est pas vraiment un endroit destiné à aider les gens à apprendre les bases d'une langue, et surtout pas "comment programmer"; C'est pour résoudre des problèmes techniques spécifiques qui se présentent dans votre travail. –

+1

J'apprécie que StackOverflow est pour "des problèmes techniques spécifiques qui se posent dans votre travail". Personnellement, je considérerais cela comme un problème technique spécifique qui a surgi dans mon travail, étant donné que j'ai posé la question spécifique "Pourquoi cela ne nécessite-t-il pas l'argument 'soi'?" et je travaillais sur un projet personnel quand je suis tombé sur la question. J'ai fait des recherches approfondies avant de poser cette question, ce qui est nécessaire. Je n'ai aucune idée de ce que vous voulez dire sur ma terminologie, mais merci pour l'avertissement. Si vous avez un meilleur endroit pour poser des questions de programmation à 02h30, j'aimerais le faire ici. –

Répondre

0

Vous essayez de l'utiliser comme une méthode statique. Dans votre exemple

class MyClass: 
    """A simple example class""" 
    i = 12345 

    def f(self): 
     return 'hello world' 

a = MyClass() 
a.f() # This should work. 

appel MyClass.f() suppose f est statique pour MyClass. Vous pouvez le faire statique:

class MyClass: 
    @staticmethod 
    def f(): # No self here 
     return 'hello world' 

MyClass.f() 
0

La chose avec self est qu'il est ajouté implicitement. Autrement dit, le code appelant indique Myclass().f(), mais l'appelé voit Myclass().f(self). Cela implique également que la méthode est appelée à partir d'une instance de Myclass, qui est placée dans la variable self. Le fait est que les méthodes sont probablement en train d'utiliser et/ou de modifier des données d'instance (sinon pourquoi seraient-elles dans cette classe?) Et il est pratique de fournir automatiquement l'instance en question. Si vous n'avez pas besoin des données d'instance, vous devez utiliser @staticmethod s'il s'agit plus d'une méthode que d'une méthode objet ou @classmethod si la méthode doit être héritée et éventuellement utilisée différemment par différentes classes. Voir @ pankaj-daga répondre pour une petite intro à staticmethods.

La syntaxe Foo.bar() est également utilisée par les fonctions importées via import Foo au lieu de from Foo import bar, ce qui est également une source possible de confusion. Cela, pour vos besoins, est une chose entièrement différente.