References to class methods in class lists in Python

I am writing a class in Python 2.6.2 that contains a lookup table. In most cases, it is simple enough that the table contains the data. Some of these cases are more complex and I want to be able to call the function. However, I am running into some problems referencing the function.

Here's some sample code:

class a:
    lut = [1,
           3,
           17,
           [12,34],
           5]

      

Where lut

is static and is expected to be permanent as well.

and now I want to do the following:

class a:
    def spam0(self):
        return (some_calculation_based_on_self)

    def spam1(self):
        return (a_different_calculation_based_on_self)

    lut = [1,
           3,
           17,
           [12,34],
           5,
           self.spam0
           self.spam1]

      

This does not compile because self.spam0

and self.spam1

undefined. I tried to use a.spam

but it's undefined as well. How can I set lut[5]

to return links to self.spam

?

Edit: This is what I plan to do:

(continuing definition class a

): import validation

# continue to somewhere in the definition of class a

def __init__(self, param):
    self.param = param

def eggs(self):
    tmp = lut[param]
    if (insect.isfunction(tmp)): # if tmp is self.spam()
        return tmp()             # should call it here
    return tmp

      

So, I want to either return a simple value or run additional code depending on the parameter.

Edit: It lut

doesn't have to be a property of the class, but the methods spam0

and spam1

must access the members of the class, so they must belong to the class.

I'm not sure if this is the best way to do it. I am still working on it.

+2


source to share


7 replies


Trivial:



class a:
    @classmethod
    def spam(cls):
        # not really pass, but you get the idea
        pass

    lut = [1,
           3,
           17,
           [12,34],
           5,
           spam]


assert a().lut[-1] == a.spam
assert a.spam() is None

      

0


source


In the clas body, you create a class; no self

, so you obviously can't turn to self.anything

. But even inside this body there is not yet a

: the name is a

associated after the class body is executed. So, while it's less obvious, in the body of the class, a

you can't reference the a.anything

.

What you can use is the bare class attribute names that have already been linked: for example, you can just use 5, spam]

at the end of your list lut

. spam

will be there as a function, how you say at some point what you want; not as a method, but most definitely NOT as a class method (I don't see classmethod

ANYWHERE in your code, why do you think the class method will magically exist in spring unless you explicitly wrap the function in classmethod

inline, directly or with a decorator?) - I suspect that your use of "class method" does not actually refer to the class type (although this is of course confusing ;-).



So, if later you need to call this function on some instance x

from a

, you will call for example. a.lut[-1](x)

, with an argument clearly there.

If you need to do something a little more subtle, it might be possible to get a bound or unbound method of some kind at different points during processing (after the class is created, or if you want a bound instance method, only after the particular instance is created). But you do not explain clearly and completely what exactly you want to do, so that we can help in great detail with these alternatives at a later stage.

+4


source


While you are in the scope of the class, you can simply write

class A:
    def spam(self):
        pass

    lut = [1, 2, 3, spam]

a = A()
print a.lut

      

gives

[1, 2, 3, <function spam at 0xb7bb764c>]

      

Remember, this is a function in your lookup table, not a number as you probably planned. You probably want to solve another problem.

+2


source


Remember, there is no such static or constant in Python. Just make it easier to read. Here's an example that generates a cached version lut

for each object:

class A(object):
    def __init__(self):
        self.__cached_lut = None

    def spam0(self):
        return (some_calculation_based_on_self)

    def spam1(self):
        return (a_different_calculation_based_on_self)

    @property
    def lut(self):
         if self.__cached_lut is None:
             self.__cached_lut = [1,
               3,
               17,
               [12,34],
               5,
               self.spam0()
               self.spam1()]
         return self.__cached_lut

a = A()
print a.lut

      

+1


source


I'm not sure I understand this question. Is this what you mean?

class a:
    lut = [1,
           3,
           17,
           [12,34],
           5]

    def __init__(self):
        self.lut.append(self.spam)

    def spam(self, a):
        print "this is %s" % a

b = a()
b.lut[-1](4)

      

this will output "this is 4".

0


source


You want the function to be bound to a class. None of the answers seem to address this.

This will not be done automatically; when you do this:

class a:
    def spam(self): print self
    lut = [1, spam]

      

lut[1]

is the spam itself, not the associated method on the object, so you can't just call lut[1]()

; you need to call lut[1](self)

.

If you specifically want to include functions in a list that can be called directly, you need to organize the function bindings, which means referring to them from an instance rather than a class. To do this, you probably want to initialize this list from __init__

:

class a:
    def spam(self): print self
    def __init__(self):
        self.lut = [1, self.spam]

      

and it is now self.lut[1]()

correct as it is a related method.

This all has the advantage that other functions can be listed for other purposes, possibly related to other objects or otherwise not expecting a parameter.

The disadvantage is that you don't reuse the list between instances; it may or may not matter to you.

0


source


You will need to move the definition a.lut

outside of the definition a

.

class a():
    def spam():pass

a.lut = [1,2,3,a.spam]

      

If you think about it, it makes sense. Using self will not work because it is self

actually only defined for the class methods for which you use the " self

" parameter . self

has no special meaning in Python and is not a reserved word; it's just a normal argument passed to the associated class methods, but it can also be this

, or foo

, or whatever.

Calling to a.lut

does not work because the definition a

is not yet complete. How is Python supposed to know, at this point in code, what a is? Within the scope of the class definition a

, a

itself is still undefined.

-1


source







All Articles