Reputation: 43
I have 2 files written in python. main.py looks like this:
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()
and cats.py that looks like this:
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()
as you can see, i am trying to make the dog talk from the cats module, is there some way to make this work? My real world app looks nothing like this btw... of course,now i get this error:
line 9, in MakeDogTalk
dog.talk()
NameError: name 'dog' is not defined
Upvotes: 3
Views: 15928
Reputation: 76194
Generally, you should try to minimize the amount of file-level code in a module. In other words, if you intend to import a file, the executable code in that file should be inside a function or class when possible. cat = Cat("pus")
and cat.MakeDogTalk()
aren't inside a function or class, so I'd move them to main.py
.
dog
isn't going to be visible inside MakeDogTalk
, so I would pass dog
as a parameter to either the Cat constructor, or the MakeDogTalk method.
Approach 1: passing the parameter into the constructor
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()
Approach 2: passing the parameter into the method
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()
It would also be simple to keep all of your dog-based logic exclusive to 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)
... But I assume you have a good reason in your real code to have the Cat handle it.
If it's really absolutely necessary to keep cat = Cat("pus")
inside cats.py
, then you'll have to put it inside a function. If it stays at the file-level scope, then MakeDogTalk
will execute before import cats
finishes executing, which occurs before the Dog
class even exists, so that's a no-go. This adds a small complication that cats.cat
will no longer be accessible from main.py, but you can still retrieve the object by returning it from the function call.
#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
It may also make sense to put the Dog
class in its own file, too. Since the Cat class depends on the Dog class, the cats file should import the dogs file. This way, you can keep your cat = Cat("pus")
in cats.py and at the file-level scope, if that's necessary for some reason.
#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")
Upvotes: 6
Reputation: 428
You are referencing dog in MakeDogTalk, but it doesnt know what it is. Add this to your MakeDogTalk:
def MakeDogTalk(self):
from main import dog
dog.talk()
Upvotes: 1