I am working with google classroom api and one of the params of a function takes a callback.
def callback(request_id, response, exception):
if exception is not None:
print 'Error adding user "{0}" to the course course: {1}'.format(
request_id, exception)
else:
print 'User "{0}" added as a student to the course.'.format(
response.get('profile').get('name').get('fullName'))
In my case the method is inside a class and as I know every python method should take a self object but in this case this function will have specific params and I am not sure how to pass the self object or should I ignore self? the issue is I plan to use self inside of the function.
Any ideas?
I think that I understand your dilema. Go ahead and include self as the first argument, since it will be passed implicitly by Python every time callback() gets called. All the other positional arguments (request_id, response and exception) will not be affected by the inclusion of self in the definition of the method's argument. i.e:
def callback(self, request_id, response, exception):
# ...
If you weren't going to use the self object inside the callback method (now a function), then you could use the #staticmethod decorator upon the function's definition, but if I'm following you straight, that's not the case here.
Edit: If you need to pass a specific parameter without compromising the nature of the callback, you can use partial, from the functools module. I would do something as follows (In this example I'm using the parameter request_id, but it could be any other(s)):
from functools import partial
partial_callback = partial(callback, request_id='12345')
Now you can pass partial_callback instead of callback wherever you need that specific argument (request_id in my example) to be passed.
Please note: If you want to pass a parameter that was not defined in the original callback function, that will raise a TypeError. If that was the case, then redefine callback, using the special syntax **kwargs, so that callback now accept a keyworded, variable-length arguments, which will be stored as key-value pairs in a dictionary called kwargs.
Just note that in order to use the arguments inside the function definition, you must refer to them as kwargs['whatever_argument_name'] (as you would do with any dictionary)
So, for example, if you want to pass an argument called extraparam, then you would need to have something as follows:
def callback(self, request_id, response, exception, **kwargs):
# ...
extraparam = kwargs.get('extraparam')
if extraparam is not None:
# ...
partial_callback = partial(callback, extraparam='whatever')
Related
What is static method and how can we explain the below code ?
#staticmethod
def get_model(**kwargs):
try:
return Model.objects.get(**kwargs)
except Model.DoesNotExist:
return
In short and maybe oversimplified: staticmethod doesn't require object of a class to run. This also means that you don't need self argument.
About the code:
This method is attempting to return single (.get()) instance of a Model that match with parameters specified in kwargs.
example:
kwargs = {"id":5, "is_alive": True}
Model.objects.get(**kwargs)
#is the same as
Model.objects.get(id=5, is_alive=True)
This can raise Model.DoesNotExists error if there is no instances of Model matching with paramaters so try/except is used.
If Model.DoesNotExists error is raised then method return None.
A staticmethod is a function not bound to an object, but is encapsulated within it ( typically to reduce outer namespace clutter, or eliminate any need to import it). It doesn't have the first self argument that a normal object method does.
I wanted to write a class function which takes Signal object as a parameter and returns its copy. Then I wanted to overload this function with an instance function that returns copy of self argument. I have a following code:
#classmethod
def copy(cls, arg):
if not isinstance(arg, Signal):
raise ValueError("Argument must be of type Signal")
result = Signal()
result.framerate = arg.framerate
return result
def copy(self):
return FragmentsSignal.copy(self)
and
Signal1 = Signal(100)
Signal2 = signal1.copy()
But after calling the function copy my code goes into infinite recursive loop and throws name of this site as an exception. My questions are:
Do I properly use python function overloading mechanism?
How can I pass *this argument to a class function within my class?
Do I properly use python function overloading mechanism?
You can't have two functions with the same name; Python does not support overloading based on the types of the arguments. The definition of the second function will override that of the first.
In essence you're calling the non classmethod function copy over and over again. You'll need to rename one of these in order to get it to work effectively.
How can I pass *this argument to a class function within my class?
I'm guessing you mean self here; passing self to another function is done as with any other arg (as you did FragmentsSignal.copy(self)). Your issue is that you're getting stumped by the recursion caused by the similar names.
I've been working with the JabberBot framework recently and am finally trying to understand its decorator #botcmd which is used to specify methods that can be executed in chat.
def botcmd(*args, **kwargs):
"""Decorator for bot command functions"""
def decorate(func, hidden=False, name=None, thread=False):
setattr(func, '_jabberbot_command', True)
setattr(func, '_jabberbot_command_hidden', hidden)
setattr(func, '_jabberbot_command_name', name or func.__name__)
setattr(func, '_jabberbot_command_thread', thread) # Experimental!
return func
if len(args):
return decorate(args[0], **kwargs)
else:
return lambda func: decorate(func, **kwargs)
I understand everything except the purpose of the if/else block at the end. What exactly does the if/else block do?
When the decorator is used normally, for example in the code snippet below, the botcmd function receives a single argument, namely the function mycmd itself, and so args = [mycmd]. The if block then executes, since len(args) = 1 and returns the decorated version of mycmd.
#botcmd
def mycmd(self,mess,args):
return 'Message'
The more difficult to intuit case happens when botcmd is called without any positional arguments, but possibly with keyword arguments. In this case, the user can easily define a new decorator with specific keyword arguments. For example, the following decorator hiddencmd can be used exactly as botcmd except that hidden will be True.
hiddencmd = botcmd(hidden=True)
#hiddencmd
def mycmd(self,mess,args):
return 'Message'
Which is then equivalent to:
#botcmd(hidden=True)
def mycmd(self,mess,args):
return 'Message'
I should also note that hiddencmd will not accept any keyword arguments, and so hiddencmd(hidden=False) would throw an error. In conclusion, it can be used as a small shortcut to increase readability and eliminate potential duplicate code.
I have written a decorator that is working correctly but i stumbled with the correct solution by trial and error and my litle knowledge about decorators tells me that something is not well defined.
The case is i'm mocking a Rest Api to do some TDD, and this Rest is behind a token security. So before making any request i first must get my user token. I'm using httpretty for mocking the API.
So far i had to register_uri in every test case, one to mock the /token resource and another to test any other resource. But i found that very cumbersome, so a came with a solution to write a simple decorator that would mock the /token and then only had to mock the tested resource.
This is my currently working decorator...
def activate_security(func):
def test_case(test_case):
httpretty.enable()
uri = 'http://{}:{}/token'.format(HOST, PORT)
httpretty.register_uri(httpretty.GET, uri,
body=dumps({'token': 'dummy_token'}),
content_type='application/json')
test_case()
httpretty.disable()
return test_case
And this is how is called.
#activate_security
#httpretty.activate
def test_case_one(self):
#Test case here
I had to pass the test_case parameter to the inner function 'cause without it it wouldn't work, and that test_case is test_case_one method, which i thought it would be passed in the func argument, but func in the outer scope holds the object at memory of test_case.
Should't be func the returned value of a decorator? If i do that, the decorator doesn't work. When the inner function is passed that parameter?
You are decorating methods, so your resulting wrapper function needs a self parameter, just like normal functions being used in a class.
All that is different is that you used a different name fro that self parameter, test_case. As it happens, the instance is callable, and calling it runs the test, so you are in essence doing self() to run the test again.
Just name the parameter self and pass it to the wrapped function:
def activate_security(func):
def wrapper(self):
httpretty.enable()
uri = 'http://{}:{}/token'.format(HOST, PORT)
httpretty.register_uri(httpretty.GET, uri,
body=dumps({'token': 'dummy_token'}),
content_type='application/json')
func(self)
httpretty.disable()
return wrapper
The wrapper() function then replaces the original test_case_one function, and when the test is run the wrapper() function is bound to the test case instance and will be passed that instance as self; in your wrapper you can then call the unbound func() by simply passing on self to it.
For debugging purposes it is often nicer to have some function attributes copied over from the wrapped function to the wrapper; the #functools.wraps() decorator can take care of these details for you:
import functools
def activate_security(func):
#functools.wraps(func)
def wrapper(self):
httpretty.enable()
uri = 'http://{}:{}/token'.format(HOST, PORT)
httpretty.register_uri(httpretty.GET, uri,
body=dumps({'token': 'dummy_token'}),
content_type='application/json')
func(self)
httpretty.disable()
return wrapper
I need to decorate a object's method. It needs to be at runtime because the decorators applied on the object depends on the arguments that the user gave when calling the program (arguments supplied with argv), so a same object could be decorated 3 times, 2 times, or not be decorated at all.
Here is some context, the program is a puzzle solver, the main behavior is to find a solution for the puzzle automatically, by automatically I mean without user intervention. And here is where the decoration gets to play, one of the things I want to is draw a graph of what happened during the execution, but I want to do so only when the flag --draw-graph is used.
Here is what I've tried:
class GraphDecorator(object):
def __init__(self, wrappee):
self.wrappee = wrappee
def method(self):
# do my stuff here
self.wrappee.method()
# do more of stuff here
def __getattr__(self,attr):
return getattr(self.wrappee,attr)
And why it did NOT work:
It did not work because of the way I built the application, when a method that did not exist in my Decorator class was called it felt back to the implementation of the decorated class, the problem is that the application always started invoking the method run that did not need to be decorated, so the undecorated fall back was used and from inside the undecorated form it always called undecorated methods, what I needed was to replace the method from the object, not to proxy it:
# method responsible to replace the undecorated form by the decorated one
def graphDecorator(obj):
old_method = obj.method
def method(self):
# do my stuff here
old_method()
# do more of my stuff
setattr(obj,'method',method) # replace with the decorated form
And here is my problem, the decorated form does not receive self when it is called resulting on a TypeError because of the wrong number of arguments.
The problem was that I couldn't use func(self) as a method. The reason is that setattr() method does not bound the function, and the function acts like it a static method - not a class method -, thanks to the introspective nature of python I've able to come up with this solution:
def decorator(obj):
old_func = obj.func # can't call 'by name' because of recursion
def decorated_func(self):
# do my stuff here
old_func() # does not need pass obj
# do some othere stuff here
# here is the magic, this get the type of a 'normal method' of a class
method = type(obj.func)
# this bounds the method to the object, so self is passed by default
obj.func = method(decorated_func, obj)
I think this is the best way to decorate a object's method at runtime, though it would be nice to find a way to call method() directly, without the line method = type(obj.func)
You might want to use __getattribute__ instead of __getattr__ (the latter being only called if "standard" lookup fails):
class GraphDecorator(object):
def __init__(self, wrappee):
self.__wrappee = wrappee
def method(self):
# do my stuff here
self.wrappe.method()
# do more of stuff here
def __getattribute__(self, name):
try:
wrappee = object.__getattribute__(self, "_GraphDecorator__wrappee")
return getattr(wrappee, name)
except AttributeError:
return object.__getattribute__(self, name)
I need to decorate a object's method. It needs to be at runtime because the decorators applied on the object depends on the arguments that the user gave when calling the program (arguments supplied with argv), so a same object could be decorated 3 times, 2 times, or not be decorated at all.
The above is unfortunately incorrect, and what you are trying to do is unnecessary.
You can do this at runtime like so. Example:
import sys
args = sys.argv[1:]
class MyClass(object):
pass
if args[0]=='--decorateWithFoo':
MyClass = decoratorFoo(MyClass)
if args[1]=='--decorateWithBar'
MyClass = decoratorBar(MyClass)
The syntax:
#deco
define something
Is the same thing as:
define something
something = deco(something)
You could also make a decorator factory #makeDecorator(command_line_arguments)
"It needs to be at runtime because the decorators applied on the object depends on the arguments that the user gave when calling the program"
The don't use decorators. Decorators are only syntactical support for wrappers, you can just as well use normal function/method calls instead.