Execute function without sending 'self' to it

10,181

Solution 1

If you don't need self, you can use the staticmethod decorator to create a method which does not receive the object as its first argument:

class Foo(object):
    @staticmethod
    def foo(bar, baz, qux):
        pass

If you're writing code which deals only with class-global data, by contrast, you can use a class method:

class Foo(object):
    global_cache={}
    @classmethod
    def set(cls, key, value):
        cls.global_cache[key] = value

If, by contrast, you're writing code which really does need to refer to the object instance -- self is part of the language. Part of the Zen of Python is that "Explicit is better than implicit", and the use of self is an example of this.

Solution 2

To call a function that exists in a class, but does not need to know anything about itself (hense removing the self argument), you can use the staticmethod.

An example of this might be

class Person:

  @staticmethod
  def barbar(arg1, arg2, arg3):
    # Has no idea of the class or instance in which this was called on.
    pass

To call this, you would do something like:

Person.barbar("hi","bye","jump")

Solution 3

You don't have to write self, that's just convention, but when a method of an object is called it is fed the object as its first argument, so you will have to give it a name. In tight code developed on my phone I've used s before, and when interfacing with C++ code I've used this, but it's usually best to use self


Update0

Oh wait, you're not defining an object method. Maybe your should be, then you run object.func(*args, **kwargs) as opposed to func(object, *args, **kwargs). I'd need to see what you're trying to do to know what's appropriate.

Solution 4

It looks like you should create your own subclass of webapp.RequestHandler and define your render_template method on it:

class MyRequestHandler(webapp.RequestHandler):
    def render_template(self, template_name, vars=dict(), is_string=False):
        # Body of render_template, with "request" replaced with "self" ...

Then you use it like so, in your views:

class SignupHandler(MyRequestHandler):
    def get(self, *args, **kwargs):
        self.render_template('signup.html')
Share:
10,181
Sergei Basharov
Author by

Sergei Basharov

Updated on June 06, 2022

Comments

  • Sergei Basharov
    Sergei Basharov almost 2 years

    Is that possible to define a function without referencing to self this way?

    def myfunc(var_a,var_b)
    

    But so that it could also get sender data, like if I defined it like this:

    def myfunc(self, var_a,var_b)
    

    That self is always the same so it looks a little redundant here always to run a function this way: myfunc(self,'data_a','data_b'). Then I would like to get its data in the function like this sender.fields.

    UPDATE: Here is some code to understand better what I mean. The class below is used to show a page based on Jinja2 templates engine for users to sign up.

    class SignupHandler(webapp.RequestHandler):
        def get(self, *args, **kwargs):
            utils.render_template(self, 'signup.html')
    

    And this code below is a render_template that I created as wrapper to Jinja2 functions to use it more conveniently in my project:

    def render_template(response, template_name, vars=dict(), is_string=False):
        template_dirs = [os.path.join(root(), 'templates')]
        logging.info(template_dirs[0])
        env = Environment(loader=FileSystemLoader(template_dirs))
        try:
            template = env.get_template(template_name)
        except TemplateNotFound:
            raise TemplateNotFound(template_name)
        content = template.render(vars)
        if is_string:
            return content
        else:
            response.response.out.write(content)
    

    As I use this function render_template very often in my project and usually the same way, just with different template files, I wondered if there was a way to get rid of having to call it like I do it now, with self as the first argument but still having access to that object.