Python namespace and global variable between files - python

I have 2 differents files. The first one, defines a lot of class:
# File 1:
class Class1:
class Class2:
#...
Those classes uses some variables that are define as global.
# File 1:
class Class1:
def __init__(self, var1):
global glob_variable_1
# Other stuff
class Class2:
#...
In the file 2, I import all the class from the first file and then use them. In this main part of this file, I define the global variables.
# File 2
from File1 import Class1, Class2
if __name__ == '__main__':
global glob_variable_1
glob_variable_1 = 10
# Other stuff
Class1(var1)
I get the error NameError: name 'glob_variable_1' is not defined.. I suppose
it's a problem of namespace and scope, but I don't really understand how it works. Can someone give me a hand? Thanks.

You have two glob_variable_1 names, one in each namespace and you must decide which one to use:
# File 1:
# defined here, outside the class
glob_variable_1 = None
class Class1:
def __init__(self, var1):
global glob_variable_1
glob_variable_1 = 42
# Other stuff
class Class2:
pass
with:
# File 2
from File1 import Class1, Class2
import File1
if __name__ == '__main__':
global glob_variable_1
# Other stuff
var1 = 1234
obj = Class1(var1)
glob_variable_1 = 666
print(glob_variable_1)
print(File1.glob_variable_1)
Gives:
666
42
Far better than using a global variable across modules is to use a function to set/get in a class or a file.

Related

How to dynamically import the class?

I have four files: main.py, MainClass.py, SigClass.py, and MyClassC.py. The entry is main.py. I rewrite the function function_a of MyClassA in MyClassC, so I need to set SigClass in main.py sig attribute, so MainClass inherits MyclassC and MyclassA in MainClass.py. My code is as follows, which does not inherit the function function_a of MyClassC.
This question explains why the weird class in the middle is used.
I have tried many methods, but I can only achieve my goal in TempClass in the main() space of MainClass.py, but in __main__ of MainClass.py Space can't do it.
How can the TempClass in the main() space be referenced in other files? I really can’t think of a way.
How can I modify the code? Or is there any other way?
The sample code is as follows:
main.py:
from MainClass import SigClass, main
SigClass.sig = "MyClassC"
main()
from MainClass import MainClass
MainClass.function_a()
print(MainClass.property)
MainClass.py:
from time import time
from SigClass import SigClass
import importlib
sig = SigClass.sig
class MyClassA:
sig = '1'
property = 'A'
#classmethod
def function_a(cls):
cls.property = 'A'
class MainClass:
pass
def main():
module_name = SigClass.sig
class_name = SigClass.sig
module_object = importlib.import_module(module_name)
module_class_object = getattr(module_object, class_name)
class TempClass(module_class_object, MyClassA):
pass
global MainClass
MainClass = TempClass
SigClass.py
class SigClass:
sig = 1
MyClassC.py
from MainClass import MyClassA
class MyClassC(MyClassA):
#classmethod
def function_a(cls):
cls.property = 'c'
pass
Thanks to #2e0byo's tips, I think the following code best meets my needs:
Import MyClassC according to SigClass.sig, and SigClass.sig is also the most important part of MainClass.
class BaseClass:
name = None
pass
class SigClass(BaseClass):
name = "SigClass"
sig = 1
class MyClassA(BaseClass):
name = "MyClassA"
property = 'A'
sig = 'a'
#classmethod
def function_a(cls):
pass
class MyClassC(MyClassA):
name = "MyClassC"
property = "C"
sig = 'c'
#classmethod
def function_a(cls):
pass
class ClassCollections(BaseClass):
classes: dict = {}
#classmethod
def add_class(cls, class_to_add: type(BaseClass)):
cls.classes[class_to_add.name] = class_to_add
SigClass.sig = "MyClassC"
ClassCollections.add_class(MyClassA)
ClassCollections.add_class(MyClassC)
class MainClass(SigClass, ClassCollections.classes[SigClass.sig], MyClassA):
pass
print(MainClass.sig)
MyClassC

How to pass variable value through classes in different files?

I have this problem.
I need to pass an "a" variable processed in an execute () method in a class A
To an execute () method located in a class B in a different file.
below my code:
fileA.py
a = 0
class A:
def execute(self):
global a
a = 10
fileB.py
from fileA import A
class B:
def execute(self):
b = a
print (b)
main.py
from fileA import A
from fileB import B
if __name__== "__main__":
first = A()
first.execute()
second = B()
second.execute()
If i try this i get an error:
AttributeError: type object 'A' has no attribute 'a'
How can I make that the value of the variable "a" (elaborated in method of class A) is also seen inside a method of class B ?
Thanks in advance
You'd better do something like this:
fileA.py
class A():
def __init__(self, a=0):
self.a = a
def execute(self):
self.a = 10
fileB.py
class B():
def __init__(self, class_a, b=0):
self.class_a = class_a
self.b = b
def execute(self):
self.b = self.class_a.a
print(self.b)
main.py
from fileA import A
from fileB import B
if __name__== "__main__":
first = A()
first.execute()
second = B(first)
second.execute()
you can skip the init part for self.a and self.b but it's much better to keep it
Use composition.
In module_a:
class A:
a = 0
def set_a(self):
self.a = 10
In module_b:
from module_a import A
class B:
a = A()
def execute(self):
print(a.a)
if __name__ == "__main__":
b = B()
b.a.set_a()
b.execute()
I think that there is a misunderstanding about global and import.
import is reponsible for 2 different things:
the module is loaded into the sys.modules list and executed
the identifiers are made available in current scope
global only says that the referenced variables should be searched only in module scope and skip any local scope.
Now what happens.
fileA declares a class (A) and a variable (a). And class A only contains an execute method and no other attribute. A.execute just happens to set the value of the module level a variable.
fileB imports the class A from fileA, but not the module level variable a. But it uses a variable a in the B.execute method, while it has never been declared neither in module scope nor in local one, hence the error.
How to fix:
At the simplest level, you could import into fileB module the variable a (that you use) instead of the class A that you do not:
fileB.py
from fileA import a
class B:
def execute(self):
b = a
print (b)

Python:Error calling class variable in a staticmethod

I am trying to call a class variable within a staticmethod, but when I called I am getting an error "hello" is not defined. any advise ?
class hello:
random1 = []
#staticmethod
def sub(x):
hello.random1.append(x -1)
sub.__func__(2)
if __name__ == "__main__":
print(hello.random1)
hello doesn't exist as a global name until you dedent out of the class definition (at which point the class is created and assigned to the global name hello). Change the code to:
class hello:
random1 = []
#staticmethod
def sub(x):
hello.random1.append(x -1)
hello.sub(2)
so sub is invoked after hello exists, and it will work.

class variable update/inherit in instance method

I'm trying to update a variable in classA and used the updated info in classB. Hence I have two questions: 1) How to update class variable in instance method? 2) How to use inherit variables from parent class?
The main idea of this program is that user enters the name, and the name var, its value csv_name_sub will be save and updated and used in class B. (i.e. used as file name)
classA(object):
def __init__(self, master, csv_name_sub):
self.entrySub = Entry(self.master,bg="grey") #user enters sth
button1 = Button(self.master,text='NEXT', command=self.gotoPage1)
def writeToFile(self):
self.csv_name_sub = str(self.entrySub.get()) #save value to var
def gotoPage1(self):
self.writeToFile()
root2=Toplevel(self.master)
self.instPage1=classB(root2)
classB(classA):
def __init__(self, master, csv_name_sub):
classA.__init__(self, master, csv_name_sub)
print(self.csv_name_sub)
self.resultFile = open(
"/Users/" + self.csv_name_sub,'w')
self.resultFileWrite = csv.writer(self.resultFile)
def main():
root = Tk()
myApp = classA(root, csv_name_sub)
root.mainloop()
But the error is:
myApp = classA(root, csv_name_sub)
NameError: name 'csv_name_sub' is not defined
I understand that csv_name_sub is created in the parent class, and its value is not inherited in the child class. But how can I access the variable value in the child class? Because the value of csv_name_sub is determined by what users entered in the parent class, I can't define it in the child class by myself.
Thanks for you help!
In your code when you initialize classA in __init__ of class B, The csv_name_sub of classA is not set because it's not inside the __init__ code of classA
I have this code and it works:
class classA():
def __init__(self, csv = ""):
print "Inside classA init"
def set_csv(self, csv):
print "Setting csv to %s" %csv
self.csv = csv
class classB(classA):
def __init__(self,csv):
print("Inside classB init")
classA.__init__(self, csv)
classA.set_csv(self, csv)
print "class B csv after set_csv %s" %self.csv
my_class = classB("abc")
Output:
Inside classB init
Inside classA init
Setting csv to abc
class B csv after set_csv abc
This will work, unless you want to create 2 different classA and class B object and want then to replicate the value, In this case you have to modify the classB.__init__ so that it'll take a classA obj as an argument and initialize itself. (In you case be sure to call set_csv before creating a classB object from class A object) Or have a csv as a static variable of classA, and write a method to modify that variable. This variable can be accessed by the class/ inherited classes, and modifying in one class is replicated across all the classes. Note that this variable will not be tied to a class object, and although you can access the variable from any subclasses, trying to modifying the variable from the subclass will return in a new static variable associated with that class and the parent class variable is not changed.
Ex:
class classA():
csv = ""
def __init__(self, csv = ""):
print "Inside classA init"
classA.csv = csv
class classB(classA):
def __init__(self,csv):
print "Inside classB init"
classA.__init__(self, csv)
my_classA = classA("abc")
print classA.csv
my_classB = classB("efg")
print classA.csv
print classB.csv #same as classA's csv
classB.csv = "lmn" #inherited static csv is masked.
print classA.csv
print classB.csv # no longer points to the classA's csv
Output:
Inside classA init
abc #initialized
Inside classB init
Inside classA init
efg #changed in Init of classB by calling init of classA
efg #classB.csv
efg #classA.csv after (classB.csv = "lmn")
lmn #classB.csv created a new static variable csv, masking the variable of classA
I hope this helps to resolve your problem.

confused value scope in python

Hi I have staring programming with c and I conld'nt understand value scope in python.
here is my code
class ScenarioEnvironment():
def __init__(self):
print(self)
class report():
config = ScenarioEnvironment()
def __init__(self):
self.config = ScenarioEnvironment()
what happens passing config and config at init()?
and I wonder the value scope which config will be class valuable?
You need to know the differences between class attribute and instance object attribute.
Maybe these codes will help you:
class TestConfig1(object):
config = 1
def __init__(self):
self.config = 2
class TestConfig2(object):
config = 1
def __init__(self):
self.config2 = 2
if __name__ == "__main__":
print TestConfig1.config
t = TestConfig1()
print t.config
t2 = TestConfig2()
print t2.config
print t2.config2
more you can see the python blog.click here
Since your question seems a bit ambiguous, I'll just comment/fix your code:
class ScenarioEnvironment():
def __init__(self,x):
self.x = x # Assigning instance variable x to constructor parameter x.
print(self) # You're printing the object instance.
class report():
# Static variable shared amongst all classes.
config = ScenarioEnvironment(None) # Assigned to new instance of ScenarioEnvironment.
def __init__(self):
# No argument, must pass one (None).
# self.config is to a new ScenarioEnvironment instance.
self.config = ScenarioEnvironment(None)
Lets try out the classes.
Output:
s = ScenarioEnvironment(None)
r = report()
>>> <__main__.ScenarioEnvironment instance at 0x026F4238>
>>> <__main__.ScenarioEnvironment instance at 0x026F4300>
>>> <__main__.ScenarioEnvironment instance at 0x026F4350>

Categories

Resources