Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass class attribute as parameter of a function of that class in Python

As the title indicates, I am trying to pass an attribute of my class as a parameter for a function of that same class. In the example below, the functionality of print_top_n() would be to print self.topn by default, but the function could also be called with a different value if need be. Is this a Python (or general programming) foul or is there a way to do this?

>>> class Example():
    def __init__(self, topn=5):
        self.topn = topn
    def print_top_n(self, n=self.topn):
        print n



Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    class Example():
  File "<pyshell#7>", line 4, in Example
    def print_top_n(self, n=self.topn):
NameError: name 'self' is not defined
like image 212
aberger Avatar asked Dec 11 '22 13:12

aberger


2 Answers

The methods are created when the class is created, and the default values are set when the method is created (See this question/answer) -- They aren't re-evaluted when the function is called. In other words, this all happens long before self has been created (Hence the NameError).

The typical approach is to use a sentinel value that you can check inside of print_top_n (None is the most common).

def print_top_n(self, n=None):
    n = self.topn if n is None else n
    print n
like image 149
mgilson Avatar answered Dec 13 '22 22:12

mgilson


One option is to use a marker object. This is a better pattern than n=None (depending on the actual intent of your api) because it will work even if someone passes n=None intentionally.

marker = object()

class Example:
    def __init__(self, topn=5):
        self.topn = topn

    def print_top_n(self, n=marker):
        if n is marker:
            n = self.topn
        print(n)
like image 26
Michael Merickel Avatar answered Dec 13 '22 21:12

Michael Merickel