osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Pylint false positives


Chris Angelico <rosuav at gmail.com>:

> On Sun, Aug 19, 2018 at 10:28 PM, Marko Rauhamaa <marko at pacujo.net> wrote:
>> The most useful use of inner classes is something like this:
>>
>>     class Outer:
>>         def method(self):
>>             outer = self
>>
>>             class Inner:
>>                 def spam(self, a, b):
>>                     outer.quarantine(a, b)
>>
>>             return Inner()
>
> That's pretty inefficient.

Hasn't become an issue for me.

> I'm not sure what you gain by having Inner be local to that method,

It's a practical way of implementing the state pattern (<URL:
https://en.wikipedia.org/wiki/State_pattern>). Your outer object behaves
differently in different states, and the inner object encapsulates the
behavior differences.

Java listeners have for ever used the pattern to implement event
listeners: <URL: http://www.fredosaurus.com/notes-java/GUI/events/anonym
ous_listener.html>.

> but here's what you lose:
>
> 1) Each instance of Inner carries with it a large class object.

Again, that hasn't been an issue for me in practice.

> 2) You can't identify these objects as being of the same type (since
> they're not).

That's a feature, not a bug. Type membership checking goes against
duck-typing.

> 3) Every invocation of method() has to execute the class body, which
> takes time.

That's what happens with every method invocation in Python regardless.

> At the price of a very small amount of encapsulation, you can make it
> actually an inner class:
>
>     class Outer:
>         class Inner:
>             def __init__(self, outer):
>                 self.spam = outer.quarantine
>
>         def method(self):
>             return self.Inner(self)

Sure, there are ways to avoid closures, but the expressive price is
usually higher than the supposed performance gain.

> Now all instances of Inner are actually instances of the same type.
> It's still local to the class, just not local to that method.

Locality to the class is usually not worth the trouble. It's good enough
to have names local to the module.

> None of this explains your aversion to creating functions in a loop at
> class scope, while still being perfectly happy doing so at function
> scope.

It had to do with populating a namespace programmatically using strings
as field/method names (which, generally, you shouldn't be doing).
Defining functions and classes dynamically during runtime is perfectly
ok.


Marko