Print the variable assignment as output - python

I have probably a really simple question: Is it possible to print the value of a variable assignment without reentering the variable name?
I mean, when we enter let's say:
foo = 5
We get the following output:
5
I tried things like foo = 5; (as if I was using MATLAB - actually it hides the output) but, couldn't find any character that does this. Even in the tutorials I looked that, this was not mentioned.

The closest you can get to have this is to create a class overriding the __setattr__ method.
class A():
def __setattr__(self,name,value):
print(value)
self.__dict__['name'] = 1
a = A()
a.x = 1
1

No, this is not possible in Python. Variable assignments do not return anything:
>>> print(exec("a = 1"))
None
>>> a
1
>>>

Related

Is there a way to replace an string with a variable of the same name? [duplicate]

This question already has answers here:
How do I create variable variables?
(17 answers)
Closed 1 year ago.
This is probably a really novice question, so forgive me.
If I know the name of an instance/variable - let's say I have a string called "variable_name" and a variable with the same name, how would I go about writing a piece of code that takes that string and converts it into something I can actually use and use class methods on, etc? Is that a thing that can happen at all?
Edit: Added some code to better articulate my question. I've got a code setup kind of like this (simplified for space):
class Class_Name:
count = 0
def __init__(self, foo, bar):
self.__class__.count += 1
self.foo = foo
self.bar = bar
def find_variable_name(class_name, number):
variable_name = "variable" + str(number)
return variable_name
variable1 = Class_Name("foo", "bar")
variable2 = Class_Name("foo2", "bar2")
variable3 = Class_Name("foo3", "bar3")
for instances in range(Class_Name.count):
print (find_variable_name(Class_Name, instances+1).foo)
This would give me the error "AttributeError: 'str' object has no attribute 'foo'" - how would I turn the object from a string to something I can work with?
You can simply use exec() function:
k = "my_str" # a string
exec(k + " = k") # my_str = "my_str"
Then, the output is:
>>> print(my_str)
'my_str'
The exec() function executes the string given it.
So, when we do exec(k + " = k"), it means, exec("my_str = k"), which assigns the value of the variable k to my_str.
This makes my_str = "my_str".
NOTE:
Be a little wary of the exec() function, especially if the value of the variable is user-inputted. Then, it could be dangerous to use.
locals() returns a dictionary of the variable bindings of the current scope.
The keys of the dictionary are strs so you can do lookup using the variable name. E.g.
>>> somevariable = 1
>>> locals()["somevariable"]
1
Of course it may be that the variable you want is not in the current scope, then it will not be in locals(). However, if it is in the global scope, you can use globals() in the same way. E.g.
>>> somevariable = 1
>>> globals()["somevariable"]
1
So in your example above, you might use a function like:
def find_variable_name(number):
return globals()["variable" + str(number)]
Which you can use as:
>>> variable1 = Class_Name("foo", "bar")
>>> find_variable_name(1).foo
'foo'
NOTE THAT this type of thing is not good programming practice. Doing this makes code harder to read and understand and maintain. Depending on your application, it might be better just to keep a Dict of your objects, indexing with the counts. E.g.
>>> d = {i: Class_Name("foo", "bar") for i in range(10)}
>>> d[1].foo
'foo'

Python class-less property / descriptor?

I have no intention of actually doing this; I'm just wondering if it's possible. I suspect it isn't.
Is it possible in Python to make a variable that resolves to the result of a function call each time it's accessed, but without accessing it via an intermediary object? With a class I can do this:
class A:
i = 0
#property
def data(self):
self.i += 1
return self.i
>>> a = A()
>>> a.data
1
>>> a.data
2
But is there some (however hacky) way I can eliminate the class? ie:
i = 0
def func():
global i
i += 1
return i
>>> data = some_magic_here(func)
>>> data
1
>>> data
2
Short answer: No.
A plain variable is never behaving like a function in Python.
There might be some "magic/tricky" way to do it (by bypassing the normal restrictions), but that would be something called "monkey patching" -- some thing that is not seen positively in the Python community.

How to make two functions share the same non global variable (Python)

Is there a way to make function B to be able to access a non global variable that was declared in only in function A, without return statements from function A.
As asked, the question:
Define two functions:
p: prints the value of a variable
q: increments the variable
such that
Initial value of the variable is 0. You can't define the variable in the global
enviroment.
Variable is not located in the global environment and the only way to change it is by invoking q().
The global enviroment should know only p() and q().
Tip: 1) In python, a function can return more than 1 value. 2) A function can be
assigned to a variable.
# Example:
>>> p()
0
>>> q()
>>> q()
>>> p()
2
The question says the global enviroment should know only p and q.
So, taking that literally, it could be done inline using a single function scope:
>>> p, q = (lambda x=[0]: (lambda: print(x[0]), lambda: x.__setitem__(0, x[0] + 1)))()
>>> p()
0
>>> q()
>>> q()
>>> p()
2
Using the tips provided as clues, it could be done something like this:
def make_p_and_q():
context = {'local_var': 0}
def p():
print('{}'.format(context['local_var']))
def q():
context['local_var'] += 1
return p, q
p, q = make_p_and_q()
p() # --> 0
q()
q()
p() # --> 2
The collection of things that functions can access is generally called its scope. One interpretation of your question is whether B can access a "local variable" of A; that is, one that is defined normally as
def A():
x = 1
The answer here is "not easily": Python lets you do a lot, but local variables are one of the things that are not meant to be accessed inside a function.
I suspect what your teacher is getting at is that A can modify things outside of its scope, in order to send information out without sending it through the return value. (Whether this is good coding practise is another matter.) For example, functions are themselves Python objects, and you can assign arbitrary properties to Python objects, so you can actually store values on the function object and read them from outside it.
def a():
a.key = "value"
a()
print a.key
Introspection and hacking with function objects
In fact, you can sort of get at the constant values defined in A by looking at the compiled Python object generated when you define a function. For example, in the example above, "value" is a constant, and constants are stored on the code object:
In [9]: a.func_code.co_consts
Out[9]: (None, 'value')
This is probably not what you meant.
Firstly, it's bad practise to do so. Such variables make debugging difficult and are easy to lose track of, especially in complex code.
Having said that, you can accomplish what you want by declaring a variable as global:
def funcA():
global foo
foo = 3
def funcB():
print foo # output is 3
That's one weird homework assignment; especially the tips make me suspect that you've misunderstood or left out something.
Anyway, here's a simpler solution than the accepted answer: Since calls to q increment the value of the variable, it must be a persistent ("static") variable of some sort. Store it somewhere other than the global namespace, and tell p about it. The obvious place to store it is as an attribute of q:
def q():
q.x += 1
q.x = 0 # Initialize
def p():
print(q.x)

Python: update value of an instance and use it in a class from imported module

I have been studying Python for three months and now I have a question that I could not solve by using google, but luckily I am able to simplify it here:
I have a var_class module:
#var_class.py
class A(object):
def __init__(self, x):
self.x = x+2
zz = A(10)
class B():
b = 0
def __init__(self):
pass
def update(self):
B.b = zz.x
and in main program I have:
#main.py
from var_class import *
b_class = B()
b_class.b # I get 0 as expected
zz = A(100)
b_class.update()
b_class.b # Instead of 102, I get 12 unexpectedly
You see my goal is to change "zz" frequently for every data input and then update a class variable 'b', and the reason I wrote zz = A(10) in var_class.py is that otherwise when I import it, module 'var_class' is missing 'zz' in 'class B', it would give error "global name zz is not defined".
However, as I write it like this now, looks like the value '10' is stuck to the class, and I am not able to change it in the main program. Don't know how to overcome this.
Thanks in advance for any help.
Answer:
alKid wrote the whole answer first, have to thanks to alexvassel and Mr. C too, would like to know if there is way to thanks them, others helped me with the knowledge, also appreciate a lot.
Easy understanding:
You can't do that, you're inside var_class module, so zz is A(10).
How about passing zz as a parameter? Like this!
class A(object):
def __init__(self, x):
self.x = x+2
zz = A(10)
class B():
b = 0
def __init__(self):
pass
def update(self, zz):
B.b = zz.x
Hope this helps!
When you do B.b = zz.x (update method) you are inside the module var_class, so zz is A(10)
python runtime finds variables by namespace. Namespace is something like scope. When B.b = zz.x executes, the runtime first searches the local namespace(the function namespace -- update), it sees no zz. Then, it goes to the module space(var_class), well we get the variable and stop searching.
The python namespace search order:
1. local namespace, the function scope
2. global namespace, the module scope
3. built-in namespace
Better not use global variables around.
your code may like this:
class B():
b = 0
def __init__(self):
pass
def update(self, zz):
B.b = zz.x
That is a matter of scope! you are using zz = A(100) in your main.py. But when you call b_class.update(), b_class has to get "some2 variable called "zz" - and the one which is available is the one you defined in your class.py - and this one still has the value A(10)!!!
To work around this, you have different options.
The dirty hack (but closest to your solution) would be to define a global variable and use ist (google "python globals" for more info on this approach).
I would suggest passing A (or A.x) to your "update" method b_class.update(A.x). This avoids globals and is more readable. Of course, you'll have to adjust B.update for the new parameter.
when you import a variable from a module, you get a copy of the variable, not the original. you need to write to the original directly.
from a.b import c
from a.b.c import var
a.b.c.var = 1
var = 2
a.b.c.var
1
var
2
Edit: So, more correctly, in python, there are objects in memory, and then there are names for the objects. When you import a module, you create two separate names, but they both point to the same object - i.e. they have a reference to the same object. It's very similar to the below code, which doesn't require any imports at all:
>>> a = 4
>>> b = a
>>> b
4
>>> a
4
>>> b = 'something different'
>>> b
'something different'
>>> a
4
Why did changing b not also change a? The sequence is like this: First, we create an object (the 4) and point the name 'a' at it. Then, we create a name 'b', and we point it at the same object. So, now looking up those names returns the same object. Now, we then go back and point the name 'b' at a different object, a string. The object 'a' is pointing to still exists, and has not changed.
New users more often trip up on this the other way, with objects like lists:
>>> a = [1,2,3,4,5]
>>> b = a
>>> b
[1,2,3,4,5]
>>> a
[1,2,3,4,5]
>>> b.append(6)
>>> b
[1,2,3,4,5,6]
>>> a
[1,2,3,4,5,6]
>>> b = b[1:3]
>>> b
[2,3]
>>> a
[1,2,3,4,5,6]
What's going on here? Well, first we create a list object, and then point the name 'a' at it. Then we create the name 'b' and point it to the same object. So, 'a' and 'b' both point to the same list. Then, we use the reference b to get the object and modify it. Note that we haven't changed what 'b' points to in this case - we grabbed the reference, and then modified the object it points to directly. So, in this case, both 'a' and 'b' will see the change - they both point to the modified object. Then, we extract a slice, and assign it to 'b'. Now, this actually creates a new object, and points 'b' at it - 'b' is no longer pointing to the original object. So now 'a' and 'b' point to different objects, and now updates to one are no longer reflected in the other.
The import case is just a special case of this.
maybe you can do this
class B():
b = 0
def __init__(self):
pass
def update(self,value):
self.b =self.b+value

Pass python variable from object to parent

I'm writing a python program that wants to keep track of a status flag from several different places. I've done some reading to discover that a Python variable passed into a function can't necessarily be modified by that function (in my case it can't). As an example:
def testfunc(self, inVariable):
inVariable = 4
def main():
myVariable = 6
print myVariable
testfunc(myVariable)
print myVariable
In this situation, the output would be:
6
6
and the 4 would never be assigned to myVariable.
Realizing that this cannot be changed, does anyone have a good workaround for this situation? Global variables, perhaps?
The situation I am dealing with is much more complex than this one, so something like returning a value and assigning it is not an easy option for me.
Thanks!
Marlon
Three solutions:
pass it a collection object containing your data
def testFunc1(var):
var[0] = 4
myvar = [6]
testFunc1(myvar)
print(myvar[0])
make the variable a global
myvar = None
def testFunc2():
global myvar
myvar = 4
myvar = 6
testFunc2()
print(myvar)
I don't generally like global variables, but depending on what you're doing it may make sense.
return the variable from the function
def testFunc3(var):
return 4
myvar = 6
myvar = testFunc3(myvar)
print(myvar)
Edit: a fourth option; as per your declaration,
def testfunc(self, inVariable):
this appears to be a class method (passing self as an argument). If the status flag is a class variable or instance variable, the method can change it as self.status = 4 and this change will be retained.
Global variables, perhaps?
Global variables are almost always a bad idea.
A variable in Python is just binding a name to a value, in testFunc all you're doing is changing the value bound to inVariable rather than changing the variable itself.
You'll need to pass an object to your function and modify its attributes. You use a built-in type like list or dict, but it's just as easy to create your own class:
>>> class Status(object):
... # Lazily use a class variable as a default for instance variables
... flag = 0
...
>>> def testFunc(status):
... status.flag = 4
...
>>> s = Status()
>>> s.flag = 6
>>> s.flag
6
>>> testFunc(s)
>>> s.flag
4
Thanks everyone for the good ideas. I ended up "cheating" on this one: the program is written with Qt so I was able to use signals and slots to accomplish my goal.
Using class variables is an interesting idea; it sort of tricks python into creating a variable that is mutable, correct? I think global variables may have been a good way to go if not for my alternative solution; this seems like one of the rare cases where they may have been a good idea.
Hopefully these answers will help others with similar problems as well.
Cheers
Marlon

Categories