Running exec inside function - python

How can you use the python exec keyword inside functions?

It's going to damage your function's performance, as well as its maintainability, but if you really want to make your own code so much worse, Python2 (this will not work in Python3, there you need to use the second alternative) gives you "enough rope to shoot yourself in the foot" (;-):
>>> def horror():
... exec "x=23"
... return x
...
>>> print horror()
23
A tad less horrible, of course, would be to exec in a specific dict:
>>> def better():
... d = {}
... exec "x=23" in d
... return d['x']
...
>>> print better()
23
This at least avoids the namespace-pollution of the first approach.

Alex's answer works slightly differently in Python 3.
Since exec() is a function in Python 3, use the following pattern-
def better():
d = {}
exec("x=23", d)
return d['x']
print better()
23
See this question for more details-
Behavior of exec function in Python 2 and Python 3

Yes.
class A:
def __init__(self):
self.a1 = ''
self.a2 = ''
def populate():
att1 = raw_input("enter a1: ")
att2 = raw_input("enter a2: ")
my_object = A()
eval("my_obj.a1 = att1")
eval("my_obj.a2 = att2")
if eval("my_obj.a2") == 2:
print "Hooray! the value of a2 in my_obj is 2"
Hope this helps

Related

Late code evaluation and also printing the code

I want to pass code to a test() routine, which has to :
print the code
execute it
and finally do stuff with the result.
should handle args in the background
For quick code snippets I can use eval(code-string), like this:
def test_eval(expr_str, expected):
global a,b
res = eval(expr_str) == expected
print(f'{res} : {expr_str}')
but for:
code with assignment
test() should do argumentless calling of fun(), even for fun(a, b...)
or longer code
the approach is unusable.
SOLVED
def test(fun,expected,args):
res = fun(*args) == expected
expr = inspect.getsource(fun)
print(f'{res} : {expr}')
def tests():fun()
def w(a,b):#args
a += b #assignment
return a.sym == "(a + b)"
a = ...
b = ...
test(w,True,(a,b))
better ideas?

print object name, when object call a function inside the class

#!/usr/bin/env python
class AA(object):
def __init__(self):
pass
def y(self):
pass
x=AA()
x.y()
When I execute x.y(), I want to print "This is 'x' call me", how should I do it ?
I hope that this will solve your issue
#!/usr/bin/env python
class AA(object):
def __init__(self):
pass
def y(self, name):
self.name = name
print("This is %s call me" % name)
x = AA()
x.y("Tarzan")
Everything is an object in Python, When you create an instance of the class it allocate memory location and that memory location is referenced by your x variable.The only object has memory location, variable doesn't have any memory location. Variable just refer to objects memory location
in your example, X is nothing just reference to your memory location
if define a variable
a = 2
that means a reference to 2
a = 1
that means a now reference to 1
Assigning one variable to another makes a new tag bound to the same value as shown below.
b = a
that means a and b both reference to 1
id() in python return memory location
print id(a)
print id(b)
output
140621897573617
140621897573617
Example 1:
>>> s1 = 'hello'
>>> s2 = 'hello'
>>> id(s1), id(s2)
(4454725888, 4454725888)
>>> s1 == s2 True
>>> s1 is s2 True
>>> s3 = 'hello, world!'
>>> s4 = 'hello, world!'
>>> id(s3), id(s4) (4454721608, 4454721664)
>>> s3 == s4 True
>>> s3 is s4 False
Example 2
>>> class Foo:
... pass
...
>>> bar = Foo()
>>> baz = Foo()
>>> id(bar)
140730612513248
>>> id(baz)
140730612513320
result
Name of object or instance is nothing just reference to memory
location
From #user1334609 's comment:
for example, we have lots of vm instance,vm1=AA(),
vm1.run_cmd("xxxx"), vm2=AA(), vm2.run_cmd("") I want to know which vm
are run some cmd
To know which VM has run the command you can just use the id(self), instead of trying to find the declared variable in code.
Two options you have now to see from which vm, command is running.
Option1: Add a member variable to class. This can give readability.
Option2: Use the id of self in y(). This avoids adding additional variable.
Example code:
#!/usr/bin/env python
class AA(object):
def __init__(self, vmname):
self.whoami = vmname
def y(self):
print "My Name is %s " % self.whoami # Option1
print "My Id is %s " % id(self) # Option2
def main():
vm1=AA("Yoda")
vm1.y()
vm2=AA("Boda")
vm2.y()
vm3=AA("Anakin")
vm3.y()
if __name__ == '__main__':
main()
This gives following output:
My Name is Yoda
My Id is 139725977256656
My Name is Boda
My Id is 139725977256720
My Name is Anakin
My Id is 139725977256784
I have posted a complete solution here:
https://stackoverflow.com/a/49331683/7386061
It works without parameters. For example you could just do:
class AA(RememberInstanceCreationInfo):
def y(self):
print("my name is '"+self.creation_name+"'")
x=AA()
x.y()
out: my name is 'x'

Dectecting a value change in Python loop

Here is a pattern I often use:
last_value = None
while <some_condition>:
<get current_value from somewhere>
if last_value != current_value:
<do something>
last_value = current_value
One application example would be to print headings in a report when, say, a person's last name changes.
The whole last_value/current_value thing has always seemed clumsy to me. Is there a better way to code this in Python?
I agree that your pattern makes a lot of sense.
But for fun, you could do something like:
class ValueCache(object):
def __init__(self, val=None):
self.val = val
def update(self, new):
if self.val == new:
return False
else:
self.val = new
return True
Then your loop would look like:
val = ValueCache()
while <some_condition>:
if val.update(<get current_value from somewhere>):
<do something>
For example
import time
t = ValueCache()
while True:
if t.update(time.time()):
print("Cache Updated!")
If you changed time.time() to some static object like "Foo", you'd see that "Cache Updated!" would only appear once (when it is initially set from None to "Foo").
Obligatory realistic programmer's note: Don't do this. I can't easily find a good reason to do this in practice. It not only adds to the line count but to the complexity.
(Inspired by Alex Martelli's Assign and Test Recipe)
I think the pattern is very clear, but you can use a generator function to hide the last_value/current_value thing.
def value_change_iterator(iterable):
last_x = None
for x in iterable:
if x != last_x:
yield x
last_x = x
for x in value_change_iterator([1, 1, 2, 2, 3, 3, 4]):
print(x)
prints
1
2
3
4
Another alternative inspired by #jedwards' answer inspired by Alex Martelli's recipe (this one keeps around the current and last values, and lets you use None as an initial value if you're so inclined, also changes the semantics from semantics I don't particularly like to other semantics I'm not sure I much like either):
class undefined:
pass
class ValueCache:
def __init__(self, value=undefined):
self.current_value = value
self.last_value = undefined
self._is_changed = False
#property
def is_changed(self):
is_changed = self._is_changed
self._is_changed = False
return is_changed
def update(self, new_value):
self._is_changed = (new_value != self.current_value)
if self._is_changed:
self.last_value = self.current_value
self.current_value = new_value
Example:
>>> v = ValueCache()
>>> v.update(1)
>>> v.is_changed
True
>>> v.is_changed is False
False
>>> v.update(2)
>>> v.is_changed
True
>>> v.is_changed
False
Or in your case:
t = ValueCache()
while True:
t.update(time.time())
if t.is_changed:
print("Cache updated!")
Same obligatory realistic programmer's note applies.

What's the equivalent of Ruby's class ##variable in Python?

In Ruby 1.9, I can use its class variable like the following:
class Sample
##count = 0
def initialize
##count += 1
end
def count
##count
end
end
sample = Sample.new
puts sample.count # Output: 1
sample2 = Sample.new
puts sample2.count # Output: 2
How can I achieve the above in Python 2.5+ ?
class Sample(object):
_count = 0
def __init__(self):
Sample._count += 1
#property
def count(self):
return Sample._count
The use is a bit different from Ruby; e.g. if you have this code in module a.py,
>>> import a
>>> x = a.Sample()
>>> print x.count
1
>>> y = a.Sample()
>>> print x.count
2
having a Sample.count "class property" (with the same name as the instance property) would be a bit tricky in Python (feasible, but not worth the bother IMHO).

how to use 'pickle'

my code(i was unable to use 'pickle'):
class A(object):
def __getstate__(self):
print 'www'
return 'sss'
def __setstate__(self,d):
print 'aaaa'
import pickle
a = A()
s = pickle.dumps(a)
e = pickle.loads(s)
print s,e
print :
www
aaaa
ccopy_reg
_reconstructor
p0
(c__main__
A
p1
c__builtin__
object
p2
Ntp3
Rp4
S'sss'
p5
b. <__main__.A object at 0x00B08CF0>
who can tell me how to use.
What are you trying to do? It works for me:
class A(object):
def __init__(self):
self.val = 100
def __str__(self):
"""What a looks like if your print it"""
return 'A:'+str(self.val)
import pickle
a = A()
a_pickled = pickle.dumps(a)
a.val = 200
a2 = pickle.loads(a_pickled)
print 'the original a'
print a
print # newline
print 'a2 - a clone of a before we changed the value'
print a2
print
print 'Why are you trying to use __setstate__, not __init__?'
print
So this will print:
the original a
A:200
a2 - a clone of a before we changed the value
A:100
If you need setstate:
class B(object):
def __init__(self):
print 'Perhaps __init__ must not happen twice?'
print
self.val = 100
def __str__(self):
"""What a looks like if your print it"""
return 'B:'+str(self.val)
def __getstate__(self):
return self.val
def __setstate__(self,val):
self.val = val
b = B()
b_pickled = pickle.dumps(b)
b.val = 200
b2 = pickle.loads(b_pickled)
print 'the original b'
print b
print # newline
print 'b2 - b clone of b before we changed the value'
print b2
which prints:
Why are you trying to use __setstate__, not __init__?
Perhaps __init__ must not happen twice?
the original b
B:200
b2 - b clone of b before we changed the value
B:100
You are able to pickle (meaning, this code works as it should). You just seem to get a result, you don't expect. If you expect the same 'output', try:
import pickle
a = A()
s = pickle.dumps(a)
e = pickle.loads(s)
print s, pickle.dumps(e)
Your example isn't, well, a typical 'pickling' example. Usually pickled objects are saved somewhere persistently or sent over the wire. See e.g. pickletest.py: http://www.sthurlow.com/python/lesson10/.
There are advanced uses of pickling, see for example David Mertz XML object serialisation article: http://www.ibm.com/developerworks/xml/library/x-matters11.html
In a nutshell, in your example, e equals a.
Don't have to care about these strang strings, you can dumps these strings to save to anywhere, just remember when you loads them, you got 'a' object again.

Categories