How can I refer to a function not by name in its definition in python?

I maintain a small library of useful functions for interacting with my company's APIs, and I ran into (I think) a neat question that I cannot find an answer to.

I often have to request large amounts of data from the API, so I do something like:

class Client(object):
    def __init__(self): = []

    def get_data(self, offset = 0):
        done = False
        while not done:
            data = get_more_starting_at(offset)
            offset += 1
            if not data:
                done = True


This works great and allows me to restart the search where I left off if something went wrong. However, since python functions are regular objects, we can do things like:

def yo():
    yo.hi = "yo!"
    return None


and then we can question about its properties later, for example:

yo.hi => "yo!"


my question is: can I rewrite my example based on a class to bind data to the function itself without referring to the function by name. I know I can do this:

def get_data(offset=0):
    done = False = []
    while not done:
        data = get_more_starting_from(offset)
        offset += 1
        if not data:
            done = True


but I would like to do something like:

def get_data(offset=0):
    done = False = [] # <===== this is the bit I can't figure out
    while not done:
        data = get_more_starting_from(offset) # <====== also this!
        offset += 1
        if not data:
            done = True
    return # <======== want to refer to the "current" object


Can you refer to the "current" object by anything other than its name? Something like "this", "self", or "memememe!" this is what I am looking for.


source to share

3 answers

I don't understand why you want to do this, but this is what the fixed point combinator allows you to do:

import functools

def Y(f):
    def Yf(*args):
        return inner(*args)
    inner = f(Yf)
    return Yf

def get_data(f):
    def inner_get_data(*args):
        # This is your real get data function
        # define it as normal
        # but just refer to it as 'f' inside itself
        print 'setting to', args = args
    return inner_get_data

get_data(1, 2, 3)



Thus, you call get_data

as usual, and he "magically" knows what f

himself means.



You could do it, but (a) the data is not meant for every function, and for every function (b) it is much easier to achieve this kind of thing with a class.

If you needed to do this, you can do something like this:

def ybother(a,b,c,yrselflambda = lambda: ybother):
    yrself = yrselflambda()
    #other stuff


The lambda is necessary because you need to defer evaluating a term ybother

until something is related to it.

Alternatively, and increasingly pointless:

from functools import partial
def ybother(a,b,c,yrself=None):
    #whatever = [] # this will blow up if the default argument is used
    #more stuff

bothered = partial(ybother, yrself=ybother)



def unbothered(a,b,c):
    def inbothered(yrself):
        #whatever = []

    return inbothered, inbothered(inbothered)


This latest version provides you with different functional objects every time, which you might like.

There are almost certainly introspective tricks for this, but they are even less useful.



Not sure if this does it the way you do, but what about using a decorator.

import functools

def add_self(f):
    def wrapper(*args,**kwargs):
        if not getattr(f, 'content', None):
            f.content = []
        return f(f, *args, **kwargs)
    return wrapper

def example(self, arg1):
    print self.content




[1, 2]
[1, 2, 3]