How to access another object

I've been trying to create a class with an __init__ method which will gather some of it's data from another object's attributes. The following code is a bare bone demonstration of my problem.

main.py

import foo
import rat
Archive = foo.Foo()
A = rat.Rat()

rat.py

import foo

class Rat:

    def __init__(self):
        self.name = "Hi there"
        self.birthday = Archive.tick

foo.py

import rat
class Foo:

    def __init__(self):
        self.tick = 5

As you can guess, this doesn't work and it tells me:

in __init__
    self.birthday = Archive.tick
NameError: name 'Archive' is not defined

I don't understand why it tells me Archive is not defined. Why can't it access the instance I just created? Why does this happen and how can I go around this?

PS: I know it's generally a terrible idea to access an object's attributes in such a public way, but the foo class is here just to have a general data gathering object, nothing serious.

Upvotes: 1

Views: 64

Answers (2)

Lukas Graf
Lukas Graf

Reputation: 32590

Archive is not defined in the scope of rat.py.

It's not enough that you define Archive somewhere in a module that gets loaded - you also need to make it available everywhere you use it by either importing it, or assign it to some other name.

So you've got two options:

  1. Import Archive from main in rat.py
  2. Pass Archive to Rat()

I would advise against importing it however. It seems you already have circular imports (foo importing rat and vice-versa). This can sometimes work, but usually it's a bad idea and should be avoided. Instead you should design and structure your code in a way where you make concious decision about what class needs to know about what, and, as a result of that, what imports the module it lives in actually needs. (Why does rat import foo? It doesn't do anything with it).

So this is what I would suggest:

rat.py

class Rat(object):

    def __init__(self, archive):
        self.archive = archive
        self.name = "Hi there"
        self.birthday = self.archive.tick

main.py

from rat import Rat
from foo import Foo

archive = Foo()
rat = Rat(archive)

Additional changes, unrelated to your problem:

Upvotes: 3

Anton Savin
Anton Savin

Reputation: 41301

rat.py

class Rat:
    def __init__(self, archive):
        self.name = "Hi there"
        self.birthday = archive.tick

main.py

Archive = foo.Foo()
A = rat.Rat(Archive)

Upvotes: 1

Related Questions