Python global variable not found when using OOP - python

Now I have the problem with the global variable that defined but when run the class object, it raises the error of "The 'variable' is not defined
Specifically,
I have created a file called __init__.py which contains global variables
Create the class_0.py, contain the function which uses defined variable in __init__.py
Create the class_1.py, to combine things which also run the function in class_0.py
__init__.py
asset = {'abc': 123, ...}
cost = {...}
class_0.py
from __init__ import *
class defc():
def function(self):
a = asset['abc']
return ...
class_1.py
from __init__ import *
from class_0 import *
class run_main():
def __init__(self):
self.defc = defc()
def run(self):
self.defc.function()
Then it raises the Error
NameError: name 'asset' is not defined
So how to solve this problem? the asset variable is the very long dictionary and I don't want to put it in a specific class due to there still other class use this.

Save all your work and try restarting your kernel.

Related

Python, define global variable in a class and import this class for main script,but that global variable is not defined

I have a basic.py file under a specific folder which defined a class:
class test_function:
def loop_unit(self,str):
global test_list
test_list.append(str)
I have another main.py which have following code
from folder import basic
test_list=[]
object=basic.test_function()
object.loop_unit('teststr')
print(test_list)
it will give an error says
name 'test_list' is not defined(it trackback to test_list.append(str) )
I actually defined global variable in the function, and I defined it at the start of the main code, why it still said this is not defined?
You defined main.test_list; test_function.loop_unit wants basic.test_list.
from folder import basic
basic.test_list = []
object = basic.test_function()
object.loop_unit('teststr')
print(basic.test_list)
Try to do this in your class definition:
class test_function:
def __init__(self):
self.test_list = []
def loop_unit(self,str):
sel.test_list.append(str)
from folder import basic
#test_list=[] --remove this line
object=basic.test_function()
object.loop_unit('teststr')
#print(test_list) ---remove this line but add this:
print(object.test_list)
Try and tell me if it works.

Importing a class by referring to it with a variable?

Edit: This question was on the assumption that I could import parts of modules without importing the whole module. It turns out that isn't the case so I decided to just import the whole module with from ex45_extras import * anyway. That makes this question pointless, but I decided to not delete this question so that some other beginner with the same question can come here and find out the sad truth: You can't import modules as parts anyways
The following is the original question:
I'm a beginner so sry for the noob question. I want to call specific classes from a module with a variable. I don't want to call the whole module. And I need to do this using this class Nav() to control which classes are being imported. Is there a way to do this? Or is there a better solution?
class Nav():
def __init__(self):
print("This is class Nav")
def play(self):
current_scene_name = "A()" # this is where the variable is defined
from ex45_extras import current_scene_name # <- this is the one
x = Nav()
x.play()
Currently it's raising this error:
This is class Nav
Traceback (most recent call last):
File "D:\Programming\Python\LPTHW_Exs\ex45\test.py", line 11, in <module>
x.play()
File "D:\Programming\Python\LPTHW_Exs\ex45\test.py", line 7, in play
from ex45_extras import current_scene_name
ImportError: cannot import name 'current_scene_name' from 'ex45_extras' (D:\Programming\Python\LPTHW_Exs\ex45\ex45_extras.py)
Class names don't have a trailing () suffix — that's how you create an instance of one (i.e. by calling it).
Anyhow, if ex45_extras.py defines a class named A:
class A:
pass
Then you could import the class via a string containing its name, and then create an instance of it as shown below:
class Nav():
def __init__(self):
print("This is class Nav")
def play(self):
import ex45_extras
current_scene_name = 'A' # this is where the variable is defined
class_ = getattr(ex45_extras, current_scene_name) # Get class.
instance = class_() # Create instance of class.
print(f'{instance=}') # -> instance=<ex45_extras.A object at 0x010D4838>
x = Nav()
x.play()
guess it's because you're trying to import an string "A()" instead of a class A()

Use only class name without namespace in isinstance

This works in a script to recognise if a is of class myproject.aa.RefClass
isinstance(a, myproject.aa.RefClass)
But how could I do it so I do not have to specify the full namespace ? I would like to be able to type:
isinstance(a, RefClass)
How is this done in Python ?
EDIT: let me give more details.
In module aa.referencedatatable.py:
class ReferenceDataTable(object):
def __init__(self, name):
self.name = name
def __call__(self, f):
self._myfn = f
return self
def referencedatatable_from_tag(tag):
import definitions
defn_lst = [definitions]
for defn in defn_lst:
referencedatatable_instance_lst = [getattr(defn, a) for a in dir(defn) if isinstance(getattr(defn, a), ReferenceDataTable)]
for referencedatatable_instance in referencedatatable_instance_lst
if referencedatatable_instance.name == tag
return referencedatatable_instance
raise("could not find")
def main()
referencedata_from_tag("Example")
In module aa.definitions.py:
from aa.referencedatatable import ReferenceDataTable
#ReferenceDataTable("Example")
def EXAMPLE():
raise NotImplementedError("not written")
For some reason calling the main from aa.referencedatatable.py will throw as it will not be able to recognise the instance of the class. But if I copy this main in another module it will work:
import aa.referencedatatable
a = aa.referencedatatable.referencedatatable_from_tag("Example")
print a
This second example works, for some reason calling this function inside the same module where the class is declared does not.
The 'namespace' is just a module object, and so is the class. You can always assign the class to a different name:
RefClass = myproject.aa.RefClass
or better yet, import it directly into your own namespace:
from myproject.aa import RefClass
Either way, now you have a global name RefClass that references the class object, so you can do:
isinstance(a, RefClass)

how to change a variable from a module inside a module in a module... (confused)

I have a variable in my main module which is changed using another module, but I want to change the variable from my main module through another module. I'm new to programmering, so I actually don't really know how to explain this stuff - sorry if I'm asking a stupid question.
The program's hierarchy looks a bit like this:
Main
---Features
---Pygame_handling
------Features
I use the "Features" module to change a variable in the "Main". I do this simply by getting the defined variable from "Features". But when I change the variable through "Pygame_handling", it is not changed in the "Features" object created in the "Main" module.
Main.py
import Features
class Simulator:
def __init__(self):
self.Features = Features.Methods()
self.variables = self.Features.dictionary
self.PyObject = Pygame_handling.Window()
Pygame_handling.py
import Features
class Window:
def __init__(self):
self.Features = Features.Methods()
dict = {"some":"dict"}
self.Features.monitor_changes(dict)
How are you initializing those classes?
Usually when I need to do something like this I code it like:
py1.py:
class Test(object):
def test_print(self):
print 'Hi!'
TEST = Test()
py2.py:
from py1 import TEST
TEST.test_print()
# Adding new stuff to the TEST initialized class
TEST.new_var = 50
print TEST.new_var
#output: 50
So now you can just use the initialized class from on that module.

Correct use of static methods

I have following simplified class named Password.py in folder1:
import random
CHARS = "ABC"
class PasswordHelper(object):
#staticmethod
def generateChars(length):
return ''.join(random.choice(CHARS) for x in range(length))
Now I have another class TestClass.py in folder2:
sys.path.append('../folder1/')
import Password
class Tester:
def whatever(self):
print Password.generateChars(3)
def main():
x = Tester()
x.whatever()
# call main method
main()
When calling python TestClass.py I get the following error: AttributeError: 'module' object has no attribute 'generateChars'. Both folders are on the same level. Is there a problem with the way I import the class files or with the static method declaration itself?
Python is not Java.
Firstly, there is absolutely no point to either the Tester or the Password classes. If you're not storing state, then don't define a class. Make both whatever and generateChars into normal standalone functions.
However, assuming you're doing this just to learn about Python classes, you have not understood that a class does not equal a module in Python. Since you've imported the Password module, you still need to refer to the PasswordHelper class:
Password.PasswordHelper.generateChars(3)
Alternatively, you can import the PasswordHelper class:
from Password import PasswordHelper
...
PasswordHelper.generateChars(3)
Finally, please follow PEP8 for your module, class and function names.
You defined the function in a class, so you need to reference it with the classname too:
print Password.PasswordHelper.generateChars(3)
Alternatively, move the function out of the class definition, at which point you do not need to use #staticmethod at all:
import random
CHARS = "ABC"
def generateChars(length):
return ''.join(random.choice(CHARS) for x in range(length))
In Python, functions do not have to be part of a class definition.

Categories

Resources