This question already has answers here:
Creating functions (or lambdas) in a loop (or comprehension)
(6 answers)
Why to use __setattr__ in python?
(7 answers)
Closed 6 months ago.
given the following snippet:
def fun(ret):
return ret
class A:
def __init__(self):
for string in ['a', 'b']:
setattr(self, string, lambda: fun(string))
>>> a = A()
>>> a.a()
'b'
I want a method a() which returns 'a' and a method b() which returns 'b'. As long as I don't use a lambda expression but setting the attribute to a simple string, the association is correct.
I think my intention is clear? So where am I wrong?
In Python, a function will lookup non-local names in the scope where it was defined or in the global scope if the name still does not exist there. If the value associated to the name changed, so will the returned value. Note that this is not specific to lambda functions.
A way around this is to create a closure by writing a helper function.
def fun(ret):
return ret
class A:
def __init__(self):
def apply_fun(item):
return lambda: fun(item)
for string in ['a', 'b']:
setattr(self, string, apply_fun(string))
print(A().a()) # 'a'
Alternative solution
In that particular case, using __getattr__ might be more suited as it is intended to dynamically return attributes.
def fun(ret):
return ret
class A:
def __getattr__(self, item):
if item in ['a', 'b']:
return lambda: fun(item)
print(A().a()) # 'a'
Related
This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 9 months ago.
In C++ you can always pass something as reference and anything that happens within the callee would be known to caller by just examining the referenced variable.
Imagine this scenario:
def x():
a = f()
print(a)
def f():
return "hello"
What I want is add a boolean flag that returns from f to x. There are several ways to do that:
make f return a tuple (str,bool)
pass a reference to a boolean variable into f
option 1 is currently not possible since there are many callers to f() and I cant change them to accept tuple as return value, so it must stay as it is.
option 2 is not possible since boolean argument is immutable (as I've learned recently).
Only f can calculate the boolean value, and x needs to know about it.
Is there any good way to achieve that? Looking for something that is not bad practice in Python coding in general.
The option that's closest to passing a pointer/reference into f would be to pass it a mutable object, like a list:
def f(ok=None):
if isinstance(ok, list):
ok.append(True)
return "hello"
def x():
ok = []
a = f(ok)
print(a, ok.pop())
But the better solution IMO would be to return a tuple, and refactor that behavior into a new function so that you're sharing code without disturbing the existing API:
def f_with_flag():
return "hello", True
def f():
return f_with_flag()[0]
def x():
a, ok = f_with_flag()
print(a, ok)
This question already has answers here:
referencing class methods in class lists in Python
(7 answers)
Calling class staticmethod within the class body?
(6 answers)
Closed last year.
I would like to define a class such as the following FunctionCatalogue class. In this class, there is a catalogue of staticmethod. These methods can thus be used without instantiating the class. The functions are labeled from tuple of integers. I defined the __call__ special method to be able to compute the relevant function values when the class is instantiated.
In order to do the same but without instantiating the class, I would had like to define the dictionary functions as a class attribute that provides the link between the tuple of integers and the give functions. But, as expected, the this_class is not defined neither FunctionCatalogue or obviously self as the class was not yet instantiated.
I wonder if there is a way to implement this or maybe a better approach to do the same ?
class FunctionCatalogue:
functions = {
(0, 0): this_class.func1,
(0, 1): this_class.func2,
}
def __init__(self, i, j):
self.i = i # with tests on i values
self.j = j # with tests on j values
#staticmethod
def func1(x):
return x + 1
#staticmethod
def func2(x):
return 2 * x + 2
def __call__(self, x):
return self.functions[(self.i, self.j)](x)
To be more clear, the idea is to be able to do
>>> my_f = FunctionCatalogue(0, 0)
>>> my_f(2)
or something like
>>> FunctionCatalogue.func1(2)
or
>>> FunctionCatalogue.functions[(0, 0)](2)
This question already has an answer here:
python getattr built-in method executes default arguments
(1 answer)
Closed 2 years ago.
I have a simple and possible dumb question.
getattr(obj, 'attribute', 2+2)
Question is - would default 2 + 2 be evaluated only in case 'attribute' is missing or it would be evaluated in any case?
Thanks
You can test this yourself by creating an object with an add function that lets you know it was called. For example, you can see the function prints "called" in bother cases indicating that the addition is evaluated regardless of whether the attribute exists on the object:
class obj:
a = "value from obj"
class N:
def __add__(self, other):
print('called')
return 5
a = N()
b = N()
getattr(obj, 'a', a + b)
# called
#'value from obj'
getattr(obj, 'z', a + b)
# called
# 5
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Replacements for switch statement in python?
Suppose I have a list in Python:
list = ('ADD', 'SUB', 'PUSH', 'POP')
I want to run a function depending on input, and that input can be any value in the list.
Instead of writing a switch case statement for each element in list, is there a more compact way of writing it?
My reasoning is for the case of the list growing in the future.
Well, there is no switch/case statement in Python.
For a small list, you want to use if/elif:
def do_stuff(x, *args):
if x == 'ADD':
return do_add(*args)
elif x == 'SUB':
return do_sub(*args)
# …
else:
raise RuntimeError('Never heard of {}'.format(x))
For a larger list, you want to make sure each case is a function (I already assumed that above, but if you had code like return args[0] + args[1], you'd have to change that into a do_add function), and create a dict mapping names to functions:
func_map = {'ADD': do_add, 'SUB': do_sub, … }
def do_stuff(x, *args):
try:
return func_map[x](*args)
except KeyError:
raise RuntimeError('Never heard of {}'.format(x))
This works because in Python, functions are normal objects that you can pass around like any other objects. So, you can store them in a dict, retrieve them from the dict, and still call them.
By the way, this is all explained in the FAQ, along with a bit of extra fanciness.
If you have some default function you'd like to call instead of raising an error, it's obvious how to do that with the if/elif/else chain, but how do you do it with the dict map? You could do it by putting the default function into the except block, but there's an easier way: just use the dict.get method:
def do_stuff(x, *args):
return func_map.get(x, do_default)(*args)
You could also use a pattern such as this (in a hurry so can't clean it up atm):
>>> class Test(object):
... def test_FOO(self):
... print 'foo'
...
... def test_BAR(self):
... print 'bar'
...
>>> def run_on(cls, name):
... getattr(cls, 'test_%s' % name)()
...
>>> run_on(Test(), 'FOO')
foo
I have a variable x in python. How can i find the string 'x' from the variable. Here is my attempt:
def var(v,c):
for key in c.keys():
if c[key] == v:
return key
def f():
x = '321'
print 'Local var %s = %s'%(var(x,locals()),x)
x = '123'
print 'Global var %s = %s'%(var(x,locals()),x)
f()
The results are:
Global var x = 123
Local var x = 321
The above recipe seems a bit un-pythonesque. Is there a better/shorter way to achieve the same result?
Q: I have a variable x in python. How can i find the string 'x' from the variable.
A: If I am understanding your question properly, you want to go from the value of a variable to its name. This is not really possible in Python.
In Python, there really isn't any such thing as a "variable". What Python really has are "names" which can have objects bound to them. It makes no difference to the object what names, if any, it might be bound to. It might be bound to dozens of different names, or none.
Consider this example:
foo = 1
bar = foo
baz = foo
Now, suppose you have the integer object with value 1, and you want to work backwards and find its name. What would you print? Three different names have that object bound to them, and all are equally valid.
print(bar is foo) # prints True
print(baz is foo) # prints True
In Python, a name is a way to access an object, so there is no way to work with names directly. You might be able to search through locals() to find the value and recover a name, but that is at best a parlor trick. And in my above example, which of foo, bar, and baz is the "correct" answer? They all refer to exactly the same object.
P.S. The above is a somewhat edited version of an answer I wrote before. I think I did a better job of wording things this time.
I believe the general form of what you want is repr() or the __repr__() method of an object.
with regards to __repr__():
Called by the repr() built-in function
and by string conversions (reverse
quotes) to compute the “official”
string representation of an object.
See the docs here: object.repr(self)
stevenha has a great answer to this question. But, if you actually do want to poke around in the namespace dictionaries anyway, you can get all the names for a given value in a particular scope / namespace like this:
def foo1():
x = 5
y = 4
z = x
print names_of1(x, locals())
def names_of1(var, callers_namespace):
return [name for (name, value) in callers_namespace.iteritems() if var is value]
foo1() # prints ['x', 'z']
If you're working with a Python that has stack frame support (most do, CPython does), it isn't required that you pass the locals dict into the names_of function; the function can retrieve that dictionary from its caller's frame itself:
def foo2():
xx = object()
yy = object()
zz = xx
print names_of2(xx)
def names_of2(var):
import inspect
callers_namespace = inspect.currentframe().f_back.f_locals
return [name for (name, value) in callers_namespace.iteritems() if var is value]
foo2() # ['xx', 'zz']
If you're working with a value type that you can assign a name attribute to, you can give it a name, and then use that:
class SomeClass(object):
pass
obj = SomeClass()
obj.name = 'obj'
class NamedInt(int):
__slots__ = ['name']
x = NamedInt(321)
x.name = 'x'
Finally, if you're working with class attributes and you want them to know their names (descriptors are the obvious use case), you can do cool tricks with metaclass programming like they do in the Django ORM and SQLAlchemy declarative-style table definitions:
class AutonamingType(type):
def __init__(cls, name, bases, attrs):
for (attrname, attrvalue) in attrs.iteritems():
if getattr(attrvalue, '__autoname__', False):
attrvalue.name = attrname
super(AutonamingType,cls).__init__(name, bases, attrs)
class NamedDescriptor(object):
__autoname__ = True
name = None
def __get__(self, instance, instance_type):
return self.name
class Foo(object):
__metaclass__ = AutonamingType
bar = NamedDescriptor()
baaz = NamedDescriptor()
lilfoo = Foo()
print lilfoo.bar # prints 'bar'
print lilfoo.baaz # prints 'baaz'
There are three ways to get "the" string representation of an object in python:
1: str()
>>> foo={"a":"z","b":"y"}
>>> str(foo)
"{'a': 'z', 'b': 'y'}"
2: repr()
>>> foo={"a":"z","b":"y"}
>>> repr(foo)
"{'a': 'z', 'b': 'y'}"
3: string interpolation:
>>> foo={"a":"z","b":"y"}
>>> "%s" % (foo,)
"{'a': 'z', 'b': 'y'}"
In this case all three methods generated the same output, the difference is that str() calls dict.__str__(), while repr() calls dict.__repr__(). str() is used on string interpolation, while repr() is used by Python internally on each object in a list or dict when you print the list or dict.
As Tendayi Mawushe mentiones above, string produced by repr isn't necessarily human-readable.
Also, the default implementation of .__str__() is to call .__repr__(), so if the class does not have it's own overrides to .__str__(), the value returned from .__repr__() is used.