5

Below is a significantly simplified version on my code. After the __init__() there are several functions.

I am trying to use functools.partial to create different versions of a basic comparison function, which references a function created earlier in the class, calculation. One version of this comparison function might be the grade_comparison seen below.

class Analysis(mybaseclass):

    def __init__(self, year, cycle):
....

    def calculation(self, subject):
        print subject

    def comparison(subject, **kwargs):
        self.calculation(subject)

    grade_comparison = functools.partial(comparison, infoList1 = ['A', 'B'])

When I run my code, there is an error, NameError: global name 'self' is not defined. I have tried adding self in many combinations that seemed logical - one example below.

self.grade_comparison = functools.partial(comparison, self, infoList1 = ['A', 'B'])

This change resulted in this error, NameError: name 'self' is not defined When I add self to the comparison function (see below):

def comparison(self, subject, **kwargs):
        self.calculation(subject)

I get this error, TypeError: comparison() takes at least 2 arguments (1 given). Please let me know if you need more context! As mentioned, this is the barebones of the code.

Mike Müller
  • 82,630
  • 20
  • 166
  • 161
Emily K
  • 230
  • 4
  • 14
  • 3
    Hint: Look at `comparison` and its parameter list. Is there a `self`? – glglgl Jan 08 '16 at 20:58
  • `functools.partial` doesn't support the descriptor protocol, so you can't use `partial` objects as methods like that anyway. – user2357112 Jan 08 '16 at 21:03
  • Could you clarify please? Why can't partial objects be used in this case? – Emily K Jan 08 '16 at 21:06
  • @skrrgwasme: You can set `self.something = partial(self.otherthing, args)` in `__init__`, but you can't set it at class level, so `Analysis.grade_comparison` can't be a `partial` object. Setting it at instance level is kind of a mess, since introspection and reflection for that gets weird and overriding it doesn't work. – user2357112 Jan 08 '16 at 21:18
  • 1
    @user2357112 Ah, I see now. I misread her code. I somehow missed that she was assigning a partial *as* class method, and not using partial outside of the class *on* a class method. My mistake. – skrrgwasme Jan 08 '16 at 21:38

1 Answers1

3

I think you can achieve what you want without partial:

class Analysis(object):

    def calculation(self, subject):
        print subject

    def comparison(self, subject, **kwargs):
        self.calculation(subject)

    def grade_comparison(self, subject):
        return self.comparison(subject, infoList1=['A', 'B'])
Anton Protopopov
  • 30,354
  • 12
  • 88
  • 93
Mike Müller
  • 82,630
  • 20
  • 166
  • 161
  • great example of how sometimes the simpler approach is the better one. i was thinking we should use decorators... – AZhao Jan 08 '16 at 22:27