|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| |||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
|
|
Get inside! Sample the range of functionality easily built with JMSL Library for Time Series Data Analysis, Heat Maps, Portfolio Optimization, Monte Carlo Simulation, Stock Price Charting and more. Download Now! |
|
#1
|
||||
|
||||
|
calling function by symbolic reference
In perl, I can call an object method by using a variable, like this:
Code:
$obj = new MyObject; $f = 'foo'; $obj->$f($args); How can I do this in python? I know that I can do this, with a simple function: Code:
def foo():
print "OK"
ref = foo
ref() # prints "OK"
But what about an instance method? |
|
#2
|
|||
|
|||
|
Re: calling function by symbolic reference
Quote:
Not sure what you mean here. But, if you want to be able to get a reference to the function via the name, simply use the globals() dict. Code:
>>> def foo():
... print "Found it!"
...
>>> globals()['foo']()
Found it!
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'foo': <function foo at 0x81612cc>, '__doc__': None}
>>> globals()['foo']
<function foo at 0x81612cc>
|
|
#3
|
||||
|
||||
|
Re: Re: calling function by symbolic reference
Quote:
I mean an instance method: Code:
class Foo:
def __init__(self):
pass
def ok(self):
print "OK"
def notok(self):
print "nope"
obj = Foo()
# say I have a list of strings that correspond to
# methods in class Foo. The string (method) to
# call is decided at runtime:
strings = ['ok', 'notok']
for s in strings:
# I want to be able to call a method using
# the variable 's' as the name of the method
obj.s() # this won't work, no method 's'
|
|
#4
|
||||
|
||||
|
There are a couple of ways to do this. One is very messy:
Code:
class Foo:
def __init__(self):
pass
def ok(self):
print "OK"
def notok(self):
print "nope"
obj = Foo()
strings = ['ok', 'notok']
for s in strings:
obj.__class__.__dict__[s](obj)
Some explaination here - class instances like obj have several built in attributes in python. One useful one is __class__ which refers to the class it is an instance of, and another is __dict__ which is a dictionary of the class instance's attributes. These attributes are actually used by Python if you have an expression like this: Code:
obj.ok() In that case, Python looks in obj's __dict__ for an attribute called "ok" It won't find it there, as ok is not an attribute of obj, but rather of it's class, Foo. So next, it looks at obj's __class__ attribute's __dict__. It finds ok there and calls it, passing obj as the first argument. So, what we are doing above is handling all that ourselves. Messy. Here's a more correct way: Code:
class Foo:
def __init__(self):
pass
def ok(self):
print "OK"
def notok(self):
print "nope"
obj = Foo()
strings = ['ok', 'notok']
for string in strings:
eval("obj.%s()" % string)
I don't even need to explain that one, do I? ![]()
__________________
Lucas Marshall |
|
#5
|
|||
|
|||
|
I'd say the first way is more correct, not to mention safer. Because I'm assuming those strings aren't hardcoded anyway. So that means they depend somewhat on user interaction. And using eval() on strings that a user passes in is extremely dangerous (for example, what if I put in 'os.system("rm -rf /")' as the string somehow?) and should always be avoided. The dict method is the most appropriate.
|
|
#6
|
||||
|
||||
|
I did mean "more correct in this instance." Obviously if you are dealing with user-input data, you wouldn't use eval. I should have clarified that.
Using eval is more "pythonish," from a readability standpoint, anyway. |
|
#7
|
||||
|
||||
|
Quote:
Thank you very much for your help! |
![]() |
| Viewing: Dev Shed Forums > Programming Languages > Python Programming > calling function by symbolic reference |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
|
|