85 votes

Appel d'une méthode de classe à partir d'une autre classe

Existe-t-il un moyen d'appeler la méthode d'une classe à partir d'une autre classe ? Je cherche quelque chose comme la fonction call_user_func_array() . Voici ce que je veux qu'il se passe :

class A:
    def method1(arg1, arg2):
        ...

class B:
    A.method1(1, 2)

2 votes

Faut-il vraiment que ce soit une méthode de classe et non une fonction ? Les méthodes statiques dans d'autres langages ne correspondent pas nécessairement à une méthode de classe en Python. Lisez ceci : dirtsimple.org/2004/12/python-n'est-pas-java.html

23 votes

@Ivo Honnêtement, qu'est-ce que ça peut vous faire s'il écrit son propre MVC avant d'avoir appris les bases ? laissez-le essayer et apprendre les bases dans le processus. Arrêtez d'être aussi condescendant envers les gens qui posent des questions.

0 votes

Peut-être dupliqué à stackoverflow.com/questions/3311987/

79voto

aaronasterling Points 25749

Mise à jour : je viens de voir la référence à call_user_func_array dans votre poste. c'est différent. utilisez getattr pour obtenir l'objet fonction et ensuite l'appeler avec vos arguments

class A(object):
    def method1(self, a, b, c):
        # foo

method = A.method1

method est maintenant un objet fonction réel que vous pouvez appeler directement (les fonctions sont des objets de première classe en python, tout comme en PHP > 5.3). Mais les considérations ci-dessous s'appliquent toujours. En d'autres termes, l'exemple ci-dessus explosera à moins que vous ne décoriez A.method1 avec l'un des deux décorateurs présentés ci-dessous, passez-lui une instance de A comme premier argument ou accéder à la méthode sur une instance de A .

a = A()
method = a.method1
method(1, 2)

Vous avez trois possibilités pour ce faire

  1. Utilisez une instance de A d'appeler method1 (en utilisant deux formes possibles)
  2. appliquer le classmethod au décorateur method1 : vous ne pourrez plus faire référence self en method1 mais on vous fera passer un cls à sa place, qui est A dans ce cas.
  3. appliquer le staticmethod au décorateur method1 : vous ne pourrez plus faire référence self o cls en staticmethod1 mais vous pouvez coder en dur les références à A dans celui-ci, bien qu'évidemment, ces références seront héritées par toutes les sous-classes de A à moins qu'ils ne remplacent spécifiquement method1 et ne pas appeler super .

Quelques exemples :

class Test1(object): # always inherit from object in 2.x. it's called new-style classes. look it up
    def method1(self, a, b):
        return a + b

    @staticmethod
    def method2(a, b):
        return a + b

    @classmethod
    def method3(cls, a, b):
        return cls.method2(a, b)

t = Test1()  # same as doing it in another class

Test1.method1(t, 1, 2) #form one of calling a method on an instance
t.method1(1, 2)        # form two (the common one) essentially reduces to form one

Test1.method2(1, 2)  #the static method can be called with just arguments
t.method2(1, 2)      # on an instance or the class

Test1.method3(1, 2)  # ditto for the class method. It will have access to the class
t.method3(1, 2)      # that it's called on (the subclass if called on a subclass) 
                     # but will not have access to the instance it's called on 
                     # (if it is called on an instance)

Notez que de la même manière que le nom de l'élément self est entièrement à votre discrétion, tout comme le nom de la variable cls variable mais ce sont les valeurs habituelles.

Maintenant que tu sais comment faire, je penserais sérieusement à if vous voulez le faire. Souvent, les méthodes qui sont destinées à être appelées de manière non liée (sans instance) doivent être considérées comme des fonctions de niveau module dans Python.

1 votes

Quelle est l'importance du cls en @classmethod def method3(cls, a, b): return cls.method2(a, b)

0 votes

L'utilisation de getattr est tout à fait inutile. A.method1 est équivalent, plus simple et plus rapide. getattr n'est utile que lorsque le nom de l'attribut auquel il faut accéder est déterminé au moment de l'exécution.

20voto

ratiotile Points 705

Il suffit de l'appeler et de fournir self :

class A:
    def method(self, x, y):
        print(x + y)

class B:
    def call_a(self):
        A.method(self, 1, 2)

b = B()
b.call_a()

Sortie :

3

8 votes

Cet exemple est faux car vous passez la référence de la classe B à la méthode de la classe A

1 votes

Je suppose que cela fonctionnera tant que tous les attributs référencés comme self.x dans la méthode existent également sur B.

3 votes

@VarunMaurya, Python utilise le typage en canard, donc les classes ne sont pas vérifiées. Comme le dit a1an, tant que vous fournissez un objet avec les bons attributs, cela fonctionnera.

6voto

Xrhstos Mpaoui Points 81
class CurrentValue:

    def __init__(self, value):
        self.value = value

    def set_val(self, k):
        self.value = k

    def get_val(self):
        return self.value

class AddValue:

    def av(self, ocv):
        print('Before:', ocv.get_val())
        num = int(input('Enter number to add : '))
        nnum = num + ocv.get_val()
        ocv.set_val(nnum)
        print('After add :', ocv.get_val())

cvo = CurrentValue(5)

avo = AddValue()

avo.av(cvo)

Nous définissons 2 classes, CurrentValue et AddValue Nous définissons 3 méthodes dans la première classe Une init afin de donner à la variable d'instance self.value une valeur initiale Une méthode set_val où nous fixons la valeur de self.value à un k Une méthode get_val où nous récupérons la valeur de self.value Nous définissons une méthode dans la deuxième classe Une méthode av où l'on passe en paramètre (ovc) un objet de la première classe. On crée une instance (cvo) de la première classe Nous créons une instance (avo) de la seconde classe Nous appelons la méthode avo.av(cvo) de la seconde classe et passons comme argument l'objet que nous avons déjà créé de la première classe. De cette façon, je voudrais montrer comment il est possible d'appeler une méthode d'une classe depuis une autre classe.

Je suis désolé pour tout inconvénient. Cela ne se reproduira plus.

Avant : 5

Entrez le nombre à ajouter : 14

Après ajout : 19

0 votes

Il serait utile d'ajouter des explications supplémentaires, afin que les lecteurs sachent pourquoi votre réponse est bonne. Les réponses sous forme de code seulement ne sont pas toujours claires pour les lecteurs novices.

4 votes

Il y a une faute de frappe dans "ocv.get_val()". Faut-il dire cvo au lieu de ocv ?

3voto

Joshua Hufford Points 41

Vous pouvez appeler une fonction à l'intérieur d'une classe avec :

A().method1()

0 votes

Si A a déjà hérité d'une autre classe (disons "Red"), dois-je inclure la classe de base dans A ? par exemple A(Red).method1()

0 votes

Je sais que c'est un peu tard, mais non, ce n'est pas nécessaire.

2voto

run_the_race Points 1700

En Python les fonctions sont des citezens de première classe, donc vous pouvez simplement les assigner à une propriété comme n'importe quelle autre valeur. Ici, nous assignons la méthode de A à une propriété de B . Après __init__ hello sera rattaché à B en tant que self.hello qui est en fait une référence à l'allo de A :

class A:
    def hello(self, msg):
        print(f"Hello {msg}")

class B:
    hello = A.hello

print(A.hello)
print(B.hello)

b = B()
b.hello("good looking!")

Imprimés :

<function A.hello at 0x7fcce55b9e50>
<function A.hello at 0x7fcce55b9e50>
Hello good looking!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X