2017-04-01 2 views
0

Ich habe 2 Dateien in Python geschrieben. main.py sieht wie folgt aus:Python: Wie man eine Methode von einem anderen Modul anruft?

import cats 

class Dog(): 
    def __init__(self, name): 
     self.name = name 
    def talk(self): 
     print("My name is "+self.name) 

dog = Dog("Boxer") 
cats.cat.talk() 

und cats.py die wie folgt aussieht:

class Cat(): 
    def __init__(self, name): 
     self.name = name 
    def talk(self): 
     print("my name is "+self.name) 
    def MakeDogTalk(self): 
     dog.talk() 
cat = Cat("pus") 
cat.MakeDogTalk() 

wie Sie sehen können, bin ich versucht, den Hund reden von der Katzen-Modul zu machen, gibt es ein Weg, um das funktionieren zu lassen? Meine reale Welt app sieht wie folgt aus nichts btw ... natürlich, jetzt habe ich diesen Fehler:

line 9, in MakeDogTalk 
dog.talk() 
NameError: name 'dog' is not defined 
+0

auch, ich laufe die main.py Datei ... – olegje31

Antwort

1

Im Allgemeinen sollten Sie versuchen, die Menge des auf Dateiebene Code in einem Modul zu minimieren. Mit anderen Worten: Wenn Sie eine Datei importieren möchten, sollte der ausführbare Code in dieser Datei möglichst in einer Funktion oder Klasse enthalten sein. und cat.MakeDogTalk() sind nicht in einer Funktion oder Klasse, also würde ich sie auf main.py verschieben.

dog wird nicht innerhalb MakeDogTalk sichtbar sein, so würde ich dog als Parameter entweder mit dem Cat-Konstruktor oder der MakeDogTalk-Methode übergeben.

Ansatz 1: Bestehen der Parameter an den Konstruktor

import cats 
#main.py 
class Dog(): 
    def __init__(self, name): 
     self.name = name 
    def talk(self): 
     print("My name is "+self.name) 

dog = Dog("Boxer") 
cat = cats.Cat("pus", dog) 
cat.MakeDogTalk() 
cat.talk() 

#cats.py 
class Cat(): 
    def __init__(self, name, dog): 
     self.name = name 
     self.dog = dog 
    def talk(self): 
     print("my name is "+self.name) 
    def MakeDogTalk(self): 
     self.dog.talk() 

Ansatz 2: Bestehen der Parameter in die Methode

import cats 

class Dog(): 
    def __init__(self, name): 
     self.name = name 
    def talk(self): 
     print("My name is "+self.name) 

dog = Dog("Boxer") 
cat = cats.Cat("pus") 
cat.MakeDogTalk(dog) 
cat.talk() 

#cats.py 
class Cat(): 
    def __init__(self, name): 
     self.name = name 
    def talk(self): 
     print("my name is "+self.name) 
    def MakeDogTalk(self, dog): 
     dog.talk() 

Es wäre auch einfach sein, alle Ihre Hund-basierte Logik zu halten Exklusiv bei main.py:

#main.py 
import cats 

class Dog(): 
    def __init__(self, name): 
     self.name = name 
    def talk(self): 
     print("My name is "+self.name) 

dog = Dog("Boxer") 
cat = cats.Cat("pus") 
dog.talk() 
cat.talk() 

#cats.py 
class Cat(): 
    def __init__(self, name): 
     self.name = name 
    def talk(self): 
     print("my name is "+self.name) 

... Aber ich nehme an, Sie haben einen guten Grund Sohn in deinem echten Code, damit die Katze damit klarkommt.


Wenn es wirklich unbedingt notwendig ist cat = Cat("pus") innen cats.py zu halten, dann werden Sie es in einer Funktion setzen müssen. Wenn es im Bereich der Dateiebene bleibt, wird MakeDogTalk ausgeführt, bevor import cats fertig ausgeführt wird, was geschieht, bevor die Dog Klasse sogar existiert, so dass es ein No-Go ist. Dies fügt eine kleine Komplikation hinzu, die cats.cat nicht mehr von main.py zugänglich ist, aber Sie können das Objekt immer noch abrufen, indem Sie es aus dem Funktionsaufruf zurückgeben.

#main.py 
import cats 

class Dog(): 
    def __init__(self, name): 
     self.name = name 
    def talk(self): 
     print("My name is "+self.name) 

dog = Dog("Boxer") 
cat = cats.do_cat_thing(dog) 
cat.talk() 

#cats.py 
class Cat(): 
    def __init__(self, name): 
     self.name = name 
    def talk(self): 
     print("my name is "+self.name) 
    def MakeDogTalk(self, dog): 
     dog.talk() 

def do_cat_thing(dog): 
    cat = Cat("pus") 
    cat.MakeDogTalk(dog) 
    return cat 

Es kann auch sinnvoll, die Dog Klasse in einer eigenen Datei zu setzen, auch. Da die Cat-Klasse von der Hundeklasse abhängt, sollte die Katzen-Datei die Hundedatei importieren. Auf diese Weise können Sie Ihre in cats.py und auf Dateiebene behalten, wenn dies aus irgendeinem Grund erforderlich ist.

#main.py 
import cats 

cats.cat.talk() 

#cats.py 
import dogs 

class Cat(): 
    def __init__(self, name): 
     self.name = name 
    def talk(self): 
     print("my name is "+self.name) 
    def MakeDogTalk(self): 
     dogs.dog.talk() 

cat = Cat("pus") 
cat.MakeDogTalk() 


#dogs.py 
class Dog(): 
    def __init__(self, name): 
     self.name = name 
    def talk(self): 
     print("My name is "+self.name) 

dog = Dog("Boxer") 
1

Sie beziehen sich auf Hund in MakeDogTalk, aber es weiß nicht, was es ist. Fügen Sie diese auf Ihre MakeDogTalk:

def MakeDogTalk(self): 
     from main import dog 
     dog.talk() 
+0

Dies funktioniert, aber wenn möglich, ich gegen die Verwendung von Kreis Importe raten würde (A Importdatei B-Datei, die aus einer Datei importiert EIN).Python löst Importe dieser Art sehr gut, aber sein Verhalten kann für diejenigen, die mit der Modul-Caching-Logik nicht vertraut sind, nicht intuitiv sein. Und es führt zu Designs, die möglicherweise nicht mit Sprachen funktionieren, die weniger intelligente Importlogik haben, wie C++. (Nicht dass das Schreiben von sprachunabhängigem Code sehr wichtig ist; aber wenn alle anderen Dinge gleich sind, können Sie auch die Lösung wählen, die einfacher zu portieren ist) – Kevin

+0

Ich stimme Ihnen zu, es ist nicht besonders gut, aber ich habe es versucht um eine Antwort zu geben, die funktioniert, was er will, und auch, ich importierte nur von der spezifischen Methode, nicht den Dateiumfang! Aber Sie haben Recht! – Kai

Verwandte Themen