5

Let's say I have a file containing the string "unpredictable_words". I would like to read in this string and then define a function as follows:

def test_unpredictable_words(self):
    do_important_stuff()

I would then like to inject this function into a class definition so that this function can be called on any instances of this class.

How can I accomplish this?

I looked a bit at this answer - https://stackoverflow.com/a/8160676/1701170 - but I don't think it does what I want, exactly, or at least I can't understand what is going on.

2 Answers 2

5
Python 2.7.3 (default, Sep 26 2012, 21:51:14) 
>>> def injected(self):
...     print 'injected'
... 
>>> class A(object):
...     pass
... 
>>> A.injected = injected
>>> a = A()
>>> a.injected()
injected
>>> def func2(self):
...     print 'func2'
... 
>>> setattr(A, 'injected2', func2)
>>> a.injected2()
func2
>>> 
Sign up to request clarification or add additional context in comments.

6 Comments

I don't follow. Your answer does not have a function name that is dynamically determined based on a string. Injecting the function isn't the hard part for me. Knowing how to define a function with a named based on a string is the part I don't understand.
I think the answer has all the necessary bits to accomplish what you need. You have a class A in which you want to inject a new method. Extract method name from a file, define any function (name doesn't matter) with the needed code, use setattr(A, method_name, your_defined_function) to inject a new method.
Functions in Python are first class citizens. Function name doesn't really matter and you can assign the same function to several variables. So your "Knowing how to define a function with a named based on a string" doesn't make sense for me. Define any function, then inject it under a different name into your class.
thanks. Your example seems to be working. I agree with you that function names should not usually matter, but I'm using Python unittest - it runs every function with a name that starts with "test" as a separate unit test, so it seems that the function name is important for using unittest.
Ok, so do something like setattr(TestCase, 'test_' + test_function_name, defined_function)
|
3

You don't need to define a function under one true name. Functions are first-class entitiens, you can pass them around and assign to variables. On top level, you use globals(), withing another function, locals() to bind a name:

>>> def foo(x):
...   return x + 1
... 
>>> name = 'unpredictable_words'
>>> 
>>> globals()['test_' + name] = foo
>>> 
>>> test_unpredictable_words(1)
2
>>> 
>>> def some_function():
...   locals()['test_' + name] = foo
...   return test_unpredictable_words(1)
... 
>>> some_function()
2
>>> 

Sometimes you still want that the function knows its name, in order to appear nicely in a stacktrace. Now test_unpredictable_words appear as foo in error messages. This is not easy to fix, since that name is stored in foo.func_code.co_name and can't be changed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.