This is clearly a scope or import issue of some kind, but I can't figure it out. Something like:
classes.py
class Thing(object):
#property
def global_test(self):
return the_global
And then...
test.py
from classes import Thing
global the_global
the_global = 'foobar'
t = Thing()
t.global_test
:(
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "classes.py", line 4, in global_test
return the_global
NameError: global name 'the_global' is not defined
Any help would be great!
"global" in Python is a variable accessible in top level within module.
This message:
NameError: global name 'the_global' is not defined
raised within classes.py means you do not have a global named the_global within your classes.py file.
Python modules do not share global variables. (well, not in the way you want them to share)
The 'global' variables only defines a variable as global inside the scope of the module
where it is used. You can not use 'global' here to access a variable outside the module
scope of the 'classes' module.
The proper solution here if you have to deal with global defines or so: move the "global"
variables into a dedicated module and use a proper import statement to import the variables
into your 'classes' module.
myvars.py:
MY_GLOBAL_VAR = 42
classes.py:
import myvars
class Thing():
def method(self):
return myvars.MY_GLOBAL_VAR # if you need such a weird pattern for whatever reason
Related
Context variables are convenient when we need to pass a variable along the chain of calls so that they share the same context, in the case when this cannot be done through a global variable in the case of concurrency. Context variables can be used as an alternative to global variables both in multi-threaded code and in asynchronous (with coroutines).
I can use contextvars in Python 3.7 and above like below and It's usually really easy:
Sample 1:
import contextvars
user_id = contextvars.ContextVar("user_id")
def f1(user, operation):
user_id.set(user.id)
f2()
def f2():
f3()
def f3():
print(user_id.get()) # gets the user_id value
Sample 2:
But when I am using the contextvars to another module's function it is not accessible, showing below error. It seems I am misunderstanding the usage of contextvars :)
NameError: name 'user_id' is not defined
test2.py
def abc():
print("inside abc")
print(user_id.get())
if __name__=='__main__':
abc()
test1.py
import contextvars
from test2 import abc
import uuid
user_id = contextvars.ContextVar("user_id")
request_id = uuid.uuid4()
def f1():
f2()
def f2():
f3()
def f3():
print("inside f3")
print(user_id.get())
user_id.set(request_id)
f1_calling = f1()
abc_calling = ABC()
Full Output:
inside f3
cdd36594-372d-438a-9bac-da53751af08a
inside abc
Traceback (most recent call last):
File "/var/www/test1.py", line 19, in <module>
abc_calling = abc()
File "/var/www/test2.py", line 3, in abc
print(user_id.get())
NameError: name 'user_id' is not defined
So my fundamental question is how can I pass and access the context variable that I set from one function and access that variable from any sub-function that is called by the main module.?
"Global" variables in Python are not actually global, but are rather attributes of the module that defines them.
You can therefore access a global variable defined in the main module from a sub-module by accessing it as an attribute of sys.modules['__main__']:
test2.py
import sys
def abc():
print("inside abc")
print(sys.modules['__main__'].user_id.get())
Demo: https://replit.com/#blhsing/TurquoiseAltruisticPercent#main.py
This is my simplified code:
main.py:
import vars, module
module.function()
module.py:
class Cage:
def __init__(self):
pass
def function():
print(mode)
from vars import *
vars.py:
from module import Cage
cage = Cage()
mode = True
When I run main.py, it gives the error code NameError: name 'mode' is not defined.
Why doesn't it give the expected value True?
This is because vars.py is making a circular import of Cage again before it can get to the line that initializes mode, resulting in from vars import * not being able to find mode as a name in the namespace of the partially-loaded vars module.
You can make module.py import vars as a module without importing its names first to let vars.py be fully loaded, and reference vars.mode in function instead so that by the time function is called, the name mode is available in the vars module:
def function():
print(vars.mode)
import vars
Demo: https://repl.it/#blhsing/FabulousOldAggregator
This works,
In main....
module.function(vars.mode)
In module.....
def function(mode):
print(mode)
In vars....
no changes
I want to refer to an object in the namespace of the file that imports the one that I am writing.
this is an example:
main.py
from imp import * # main is importing the file I'm writing
...more code...
obj=1 # main defines obj
f() # f(), defined in imp, needs to use obj
...more code using obj...
This is the file that defines f():
imp.py
def f():
return obj # I want to refer to main's obj here
error on runtime:
error: global name 'obj' is not defined
How can it be done?
Thanks.
Relying on global variables across modules is not really a good idea. You should pass obj as a parameter to the function f(), like this:
f(obj)
Then just declare the parameter in the function:
def f(obj):
# code to operate on obj
return obj
I am trying to develop a robot for Skype and I am having difficulties with certain classes and how to use only one instance instead of creating a new one within another file.
I have many files in which the robot runs from and I want to only use one instance via a Global.py file:
from classes import class_Core
from classes import class_Skype
from classes import class_Message
from classes import class_Commands
global Core, Skype, Message, Commands
Core = class_Core.Core()
Skype = class_Skype.Skype()
Message = class_Message.Message()
Commands = class_Commands.Commands()
I also have a Skypebot.py file which imports the Global.py file:
import Global
However, when I run Skypebot.py and use a function from Core in the Skype class:
class Skype:
def __init__(self):
Core.Log("Initialising Skype!")
I get an trace back:
Traceback (most recent call last):
File "C:\Users\Connor\Desktop\Skypebot 0.4\Skypebot.py", line 1, in <module>
import Global
File "C:\Users\Connor\Desktop\Skypebot 0.4\Global.py", line 9, in <module>
Skype = class_Skype.Skype()
File "C:\Users\Connor\Desktop\Skypebot 0.4\classes\class_Skype.py", line 8, in
__init__
Core.Log("Initialising Skype!")
NameError: global name 'Core' is not defined
Can anybody help me on this? Thanks!
You want this in skypebot.py, instead of import Global:
from Global import Core
You also don't need the global Core, Skype, Message, Commands line, since those variables are already being declared at a global scope within Global.py, as doukremt mentioned. The "global" keyword would be used if you then wanted to access/modify a global variable instance a function or method, e.g.
var = 3
def some_func():
var = 2 # This creates a locally-scoped variable named var, and assigns it to 2.
def some_other_func():
global var
var = 2 # This sets the globally-scoped variable var to 2.
Given below is a snippet from a class of which I am trying to create objects and getting error:
class FoF(object):
def __init__(self,path):
filepath=[]
filepath.append(self.FileOrFolder(path))
Upon executing which I get the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "PathOps.py", line 6, in __init__
def __init__(self,path):
NameError: global name 'filepath' is not defined
After which I tried:
filepath=[]
class FoF(object):
def __init__(self,path):
global filepath.append(self.FileOrFolder(path))
And again:
File "<stdin>", line 1, in <module>
File "PathOps.py", line 6, in __init__
global filepath.append(self.FileOrFolder(path))
NameError: global name 'filepath' is not defined
What is causing the error and how do I fix it?
Try using insted of global the special word self.
So something like this
class FoF(object):
def __init__(self,path):
self.filepath=[]
self.filepath.append(self.FileOrFolder(path))
The reason this error comes up is because what python thinks you're trying to do is one of two things:
Either you're trying to reference a global variable called filepath -- which is clear that's not what you're trying
What's not so clear is that you could also define a class attribute called filepath -- the only problem with that is that you can't define a class attribute with a function of that class. You can only do so within the class -- outside a class function
So in order to declare variables within a function you have to use the word self before it.
Edit** if you want it to be an attribute of the class -- as I'm assuming is what you meant you could do so like this:
class FoF(object):
filepath=[]
def __init__(self,path):
self.filepath.append(self.FileOrFolder(path))
I don't think you're giving us enough information. For example:
>>> class FoF(object):
... def __init__(self, path):
... junk = []
... junk.append(path)
...
>>> foo = FoF('bar/path')
produces no error.
What, exactly, are you trying to do?