Hydra
Hydra

Reputation: 373

How can I reference a variable from another file

I have two files: client.py and ItemDatabase.py. I'm trying to store item values in a separate source file, similar to a database, and then call on those item values when I need them in other source files. Here I have the classes Item and WeaponData, which both hold information about the item, and then the instance itself is created in the ItemDatabase. When I want to get that information in the other source file through a print statement I am getting an error: NameError: name 'tinder_sword' is not defined, even though my IDE recognizes that tinder_sword is apart of ItemDatabase.

In client.py:

from ItemDatabase import *
import pygame as pg


class Item:
    def __init__(self):
        self.name = ""
        self.description = ""
        self.max_stack_size = 0
        self.icon = ""


class WeaponData(Item):
    def __init__(self):
        super().__init__()
        self.damage = 0
        self.range = 0
        self.cooldown = 0
        self.max_condition = 0
        self.max_stack_size = 1

print(tinder_sword.name)

In ItemDatabase.py:

from client import *

tinder_sword = WeaponData()
tinder_sword.name = "Tinder Sword"
tinder_sword.description = "Weak and flimsy, but it's not bad for a starter weapon."
tinder_sword.damage = 10
tinder_sword.cooldown = 0.2
tinder_sword.max_condition = 75

Upvotes: 0

Views: 589

Answers (2)

Parthanon
Parthanon

Reputation: 388

  • Hey! So the issue with your code is not that the variable is not getting imported. The issue is that you are importing client into ItemDatabase.py and then importing ItemDatabase into client.

When you import a python file all the code that is not in a scope gets run. So if you follow the logic: in client.py

from ItemDatabase import *

so now we run the code in ItemDatabase

from client import *

so now we run the code in client But now python has already imported ItemDatabase so it skips it. Now we create the 2 classes in client.py and we run the last line of code:

print(tinder_sword.name)

Except. We have not actually run the code to create tinder_sword yet. Because we are still in the phase of importing client into ItemDatabase.

Importing files needs to flow one way, like a river. If you need two files to use data from each other then you can create a class called Populater in file2. File 1 imports Populator, gives it the values that file 2 needs, and then exits. File 2 never needs to import file 1 but it's populate class will still have file 1's values. This is like sending a power boat up the river to fetch some logs and the driving the boat back down the river to be used there.

This is however not a good way to write programs! It usually means that the way you are thinking about your application is too intertwined and will probably lead to more bugs like this down the line.

The "Nice" way to write a program like this is to do what is called "Separation of concerns". One file focuses on doing one thing only. But doing that one thing well. For example: You might have a SwordBuilder file. It creates amazing swords. Then you might have a storage class. It is focused on storing and reading any items you might have to the filesystem so your games can be saved.

Hope this helps!

Upvotes: 1

Boyke Ferdinandes
Boyke Ferdinandes

Reputation: 411

trying to help here, usually I would create a config.py file contain classes and stuff as what you have in client.py

then import it in doSomething.py then do the printing in there

import pygame as pg


class Item:
    def __init__(self):
        self.name = ""
        self.description = ""
        self.max_stack_size = 0
        self.icon = ""

class WeaponData(Item):
    def __init__(self):
        super().__init__()
        self.damage = 0
        self.range = 0
        self.cooldown = 0
        self.max_condition = 0
        self.max_stack_size = 1
import client.py

tinder_sword = client.WeaponData()
tinder_sword.name = "Tinder Sword"
tinder_sword.description = "Weak and flimsy, but it's not bad for a starter weapon."
tinder_sword.damage = 10
tinder_sword.cooldown = 0.2
tinder_sword.max_condition = 75

print(tinder_sword.name)

Upvotes: 0

Related Questions