Question

I know the question header sounds weird, but since English is not my first language, I find it very hard to formalize. However, I might be able to explain it with bit more text.

The problem is, that I'm trying to create a class called "Foo" for example.

# ../myProject/Foo.py

class Foo:
    '''Represents an example class for stackoverflow'''

Now all of Foo class' instances have function attribute, which simply holds a function which can be executed via the instance. Also, there's a parameters attribute, a tuple or a list, which holds parameters which should be used when the function gets called.

    def __init__(self, function, parameters):
        self.function = function
        self.parameters = parameters

    def callFunction(self):
        if self.function:
            self.function(*self.parameters)

This seems to be working fine, however, the problem is, that I want to give it a default value, to change an attribute of the instance. I basically wanna do the following:

def __init__(self, function=setattr, \
        parameters=(self, "togglableAttribute", not self.togglableAttribute)):

And doing this will raise NameError: name 'self' is not defined. How should I implement this in order for it to work, or should I come up with a workaround?

Was it helpful?

Solution

self is the typical variable name used to describe the instance. However, default arguments are evaluated when the function is created (at class creation time). Of course self doesn't exist yet because the class doesn't even exist yet -- The class is still in the process of being built.

The typical way to do this is to check for a sentinel;

def __init__(self, function=setattr, parameters=None):
    if parameters is None:
       parameters = (self, "togglableAttribute", not self.togglableAttribute)

See my answer here (and the comments below it) for a discussion of various objects that you can use as your sentinel and the various pros and cons of each.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top