2017-07-07 2 views
1

J'ai écrit une fonction en Python qui est censée fonctionner de manière similaire à une fabrique en Java, car elle installe la classe correcte pour les paramètres donnés et renvoie cette instance.Renvoyer une instance d'objet Python d'une classe interne d'une fonction

Un exemple minimal avec une seule classe dans la fonction serait la suivante:

def create_object(param): 

    class SpecialClass(ParentClass): 
     def func(self, param): 
      doSomething() 

    class_instance = SpecialClass(param) 
    return class_instance 

Je peux utiliser parfaitement cet objet lorsque j'appelle cette fonction de l'extérieur. Venant d'un arrière-plan Java, je suppose que cela a quelque chose à voir avec le typage dynamique en Python mais je ne sais toujours pas pourquoi cela fonctionne réellement. L'étendue où cette classe est connue n'est-elle pas juste au sein de la fonction elle-même?

+0

Votre question n'est pas claire. Pourquoi * ne fonctionnerait-il pas? Et pourquoi cela aurait-il quelque chose à voir avec le typage dynamique? –

+0

Oui, qu'est-ce que cela a à voir avec le typage dynamique? Aussi, @DanielRoseman, il veut dire qu'en Java, la portée de la classe et des objets à l'intérieur d'une fonction est seulement à l'intérieur ... mais Florian dit que cela ne semble pas être le cas ici –

+1

Je ne vois toujours pas Qu'est-ce que cela a à voir avec la portée. Vous renvoyez un objet de la fonction, et cet objet peut être transmis partout où vous le souhaitez, même en Java. –

Répondre

3

Pour répondre à votre question, vous avez retourné un objet et Python vous permettra de l'utiliser quel que soit l'endroit où la classe d'origine a été définie. Il n'y a pas de classes privées en Python et les fonctions elles-mêmes sont des objets, donc quand vous retournez l'objet, tout en dehors de cette fonction voit l'objet comme une instance de create_object.SpecialClass.

En pratique, les usines ne sont pas quelque chose que vous faites en Python. Vous devriez utiliser une méthode de classe qui retournera simplement une instance de la classe. Vous pouvez en lire plus à ce sujet ici:

Si vous êtes confus juste google python classmethod decorator et il ya quelques bonnes explications Stackoverflow de la façon de les utiliser.

+0

Ce n'est pas ce qu'il a demandé. Il veut savoir que cela a fonctionné, c'est-à-dire en utilisant un objet d'une classe interne dont la portée est limitée. Pourquoi le comportement? –

+0

@AakashVerma, j'ai mis à jour pour expliquer cela, mais je garde toujours le découragement de faire des usines car il est impythonique –

+0

Je m'attendais à moitié à entendre cela et je suis vraiment heureux que vous me disiez.Je vais voir si je peux changer mon code pour qu'il soit aussi lisible que maintenant tout en se débarrassant de la fonction d'usine. Pour le reste, je pense que cela répond à ma question. Merci! – Florian

-2

Excuse mon affreux Java, mais je ne peux pas voir comment votre code Python est différent de ceci:

class NestedScope { 
    public static void main(String[] args) { 
     OuterClass oc = new OuterClass(); 
     oc.bar().foo(); 
    } 
} 

class OuterClass { 
    class InnerClass { 
    public void foo() { 
     System.out.println("in here"); 
    } 
    } 
    public InnerClass bar() { 
    return new InnerClass(); 
    } 
} 

Ici, dans la classe principale, je référence à l'objet de classe interne de classe sans cette classe jamais être en portée, et je peux appeler avec succès sa méthode foo().

+0

Si je vois la différence, vous ne pourrez pas appeler directement foo() sans votre indirection via cette méthode. C'est parce que vous ne pouvez pas déclarer un objet de type InnerClass si votre classe NestedScope ne le connaît pas. Pour cela, vous devez également importer InnerClass. Cependant, en python je n'ai pas (et je suppose que je ne peux pas?) Même importer cette classe dans ma fonction. Alors oui, je vois une différence. – Florian

+0

Votre code est [ici] (https://ideone.com/eOE5iW) et cela fonctionne mais c'est totalement différent de ce dont nous parlions. Créer des objets d'une classe, qui est à l'intérieur d'une fonction de la classe externe, en dehors de la fonction n'est simplement pas le cas représenté par votre code. Cela ne peut pas arriver, mec. Votre code consiste à créer et renvoyer un objet de la classe interne via une fonction lorsque la classe n'est pas à l'intérieur d'une fonction dans la même classe supérieure. et ne pas créer à l'extérieur, l'objet d'une classe présente à l'intérieur d'une fonction. –

+0

Si vous devez créer l'objet d'une classe dans la fonction, vous devez le créer dans la même fonction et vous ne pouvez pas le transmettre. Peut-être utiliser cette classe interne pour créer un getter à un champ de la classe externe, puis créer un objet et appeler le getter. Tout cela se passe à l'intérieur de la fonction dans laquelle la classe interne est présente. –