I want to do the following in python:
def func1():
var1 = "something"
def func2():
print var1
What is the correct mode to do this ? I've not found in documentation at all
PS. If possible, it's not my plan to make that 'var1' a global variable.
Thanks.
I assume you don't want to pass the variable as a parameter between the function calls. The normal way to share state between functions would be to define a class. It may be overkill for your particular problem, but it lets you have shared state and keep it under control:
class C:
def func1(self):
self.var1 = "something"
def func2(self):
print self.var1
foo = C()
foo.func1()
foo.func2()
No, it is not possible to do things like that. This is because of something called "scope". You can either create a module-level variable or place it in an OOP construct.
Well your func2() is trying to print a variable in the scope of another function. You can either
Return the value of var1 when calling func1 (eg. def func2(): print func1() }
Call func2 from func1 and pass the value of var1
You could try something like
def func1():
var1 = "something"
return var1
def func2():
print func1()
If you need func1 to do more things than just define var1, then maybe what you need is to define a class and create objects? See http://docs.python.org/tutorial/classes.html
You could try:
filename.py:
def func1():
var1 = "something"
def func2():
var = __ import__('filename').var1
print var
Related
I'm trying so check if a variable exists, but inside a function.
I was taught that, to do this, the only thing you needed to do was:
'a' in locals()
Unfortunately, things turned out to be a little bit more difficult than I expected.
I tried to define a function that included this method.
q=[1,2,3]
def f():
print('q' in locals())
When I run this function, it returns:
False
The problem is, as we can see, that q is a variable, so when I run the same command, but outside the function:
'q' in locals()
It returns:
True
Is there a way to solve this?
You may test for the existence of your list q in the globals() dictionary, since it exists in global scope, not the local scope of your function f, i.e.:
def f():
print('q' in globals())
As pointed out in the comments, testing the existence of variables using their string names like this is not ideal and you may instead use a try/except:
def f():
try:
# Do something with q
print(q)
except NameError:
print("Variable not defined")
When you code the following lines
q=[1,2,3]
def f():
print('q' in locals())
f()
Here, variable 'q' is not local to function f() as it is declared outside the function scope.Inside the function, q can be accessed using global.
But, outside the function 'q' is a local variable.
Therefore, when you check inside the function
q=[1,2,3]
def f():
print('q' in locals())
it will return False
But if you declare inside the function and check as follow:-
def f():
q=[1,2,3]
print('q' in locals())
It will return True as q is now local to the function.
Also if you check 'q' inside the function as global it will return True as 'q' is declared outside the function and has global scope.
q=[1,2,3]
def f():
print('q' in globals())
f()
Output
True
you can use
hasattr(obj, "var")
and replace obj with self
class test():
def __init__(self):
self.a = 1
def check(self, var):
return hasattr(self, var)
t = test()
print(t.check("a"))
print(t.check("b"))
output
True
False
I want to use a class in Python to simulate a 'struct' in C++. Also, I need it in global form as I am using it in many functions and I do not want to pass parameters.
How do I do this(create global objects of a class).
My attempt was :
class MyClass():
//Class Constuctor
global ob1 = Myclass()
def func1():
ob1.name = "Hello World"
def func2():
print(ob1.name)
func1()
func2()
This gives me an 'Invalid Syntax' error, how did I go wrong, or is there a more efficient method to do this?
Note that I have like 10 values, so the class is going to be a pain anyway.
In your code it is not necessary to explicitly place the global modifier, this variable is global by default.
class MyClass():
def __init__(self):
self.name = ""
ob1 = MyClass()
def func1():
ob1.name = "Hello World"
def func2():
print(ob1.name)
func1()
func2()
Output:
Hello World
In addition the use of global is as follows:
global variable
variable = your_value
This might seem like a rather weird thing to do, but I was curious if it was possible to implicitly pass a variable down a call chain in Python without passing it as an argument. To better illustrate here is an example:
Here is the "normal" way:
def three(something):
print(something)
def two(something):
# ...
three(something)
def one(something):
# ...
two(something)
And here is what I want to be able to do:
def three():
# something is defined implicitly
print(something)
def two():
# ...
three()
def one(something):
# somehow define something inside a context
# for this activation
two()
For the purpose of this, one, two and three are not in the same class or even the same module.
You don't want to do this.
If you are really convinced that you want to torture yourself, then you could create a separate thread and run the call to one() in that thread. Then just use threading.local for the shared state.
You really don't want to do this.
Here's how you can use thread local storage:
import threading
state = threading.local()
def three():
# something is defined implicitly
print(state.something)
def two():
# ...
three()
def one(something):
# somehow define something inside a context
# for this activation
def inner():
state.something = something
two()
t = threading.Thread(target=inner)
t.start()
t.join()
if __name__=='__main__':
one(42)
one(24)
If you must, you can assign values to the function object itself. Ideally, both three() and two() would perform checks that would raise better exceptions than an AttributeError if 'something' is not set correctly.
def three():
print(three.something)
def two():
three.something = two.something
three()
def one(something):
two.something = something
two()
You could take advantage of lexical closures - define two() and three() within the definition of one().
>>> def one(something):
... def two():
... three()
... def three():
... print something
... two()
...
>>> one(1)
1
You can use __builtins__ to hold your "global variables".
>>> __builtins__.something = "Hello world!"
>>> def foo():
print something
>>> foo()
Hello world!
This can help you avoid passing variables explicitly.
This is a terrible hack. IMHO, you really don't need to do that.
I'm trying to do something like this:
import threading
def func1(a,b):
def func2():
t=threading.Thread(target=func3)
return t
return func2
func2=func1(a,b)
func2()
I have a restriction(the language I'm using is python with some restricted functions) not to use the args parameter for the Thread function instead I want to pass a and b as parameters to func3. How can I do this using closures?
You can use a lambda:
t=threading.Thread(target=lambda: func3(a,b))
The values of a and b will be held in a closure, even after func1 exits.
Instead of a lambda, you can create a named function:
def thread_func():
func3(a,b)
t = threading.Thread(target=thread_func)
In the absence of lambda I might look into functools.partial. If that isn't allowed, you could probably do:
import threading
def func1(a,b):
def func2():
def func4():
return func3(a,b)
return threading.Thread(target=func4)
return func2
func2=func1(a,b)
func2()
def A():
def B():
#do something
a = A()
a.B()
Why isn't the above (such simple code) possible in Python? Is there a 'pythonic' (legible, unsurprising, non-hacky) workaround that does not turn A() into a class?
Edit 1: The above was explained to me that B is local to A, thus it only exists as long as A is being evaluated. So if we make it global (and be sure not to have it overriden), then why doesn't this work?
def A():
def B():
#do something
return A()
a = A()
a.B()
It says it's returning a 'NoneType' object.
Because a function definition just creates a name in the local namespace. What you are doing is no different than:
def f():
a = 2
and then asking why you can't access a from outside the function. Names bound inside a function are local to the function.
In addition, your proposed code is strange. when you do a = f(), you are setting a to the return value of the function. Your function returns nothing, so you can't hope to access anything through the return value. It is possible to return the inner function directly:
def f():
def g():
return "blah"
return g
>>> func = f()
>>> func()
'blah'
And this can indeed be useful. But there isn't a generic way to access things inside the function from outside except by modifying global variables (which is usually a bad idea) or returning the values. That's how functions work: they take inputs and return outputs; they don't make their innards available to the outside word.
To call B with the syntax you want, use:
def A():
def B():
print("I'm B")
A.B = B
return A
a = A()
a.B()
A.B()