[code-quality] Bad coding style?

Ian Cordasco graffatcolmingov at gmail.com
Sat Feb 8 15:25:32 CET 2014


On Sat, Feb 8, 2014 at 7:05 AM, Mark Shannon <mark at semmle.com> wrote:

> On 06/02/14 18:51, Thomas Heller wrote:
>
>> I sometimes have code like this:
>>
>> class Foo:
>>
>>      def spam(self):
>>          ....
>>
>>      from somewhere import method
>>      from somewhere import CONSTANT
>>
>>      def blah(self):
>>          ....
>>
>> where CONSTANT defines a class attribute, anbd method
>> is a method that I would like to call like any other
>> methor (self.spam(), or self.blah()).
>>
>> This works nicely and is a compact coding style, however
>> frosted complains about unused imports.
>>
> frosted is wrong here as CONSTANT is used to build the locals() dictionary
> used to build the class Foo
>
>
>
>> Should I fix my coding habits, or should frosted by fixed?
>>
> Both ;)
> Don't forget "Readability counts".
>

I would have to agree with everything said so far but I am frankly a little
surprised that no one has suggested an alternate way of writing your class.
If, this is a fairly common pattern for you, instead of writing an import
like that and taking advantage of how Python builds classes, you could
define the method and the constant in a different class and then inherit
from that. This is one place Python's multiple inheritance is actually a
huge benefit.

For example, in a.py

class FooMixin:
    CONSTANT = 'foo'

    def method(self, *args, **kwargs):
        ...

And in b.py

from a import FooMixin


class Bar(FooMixin, OtherParentClass):
    def spam(self):
        ...

    def biz(self):
        ...

The important thing to note is that if `OtherParentClass` overrides methods
in FooMixin and should take precedence it should be declared as a parent
class after the mixin (as above).

This does not rely on the user understanding how classes are created by
Python. It is explicit, and it's readable. The issue, of course, occurs
when you are perhaps not using the same method(s) and constant(s) each
time. If you are defining it my dynamically, you should be able to do
something like this:

from somewhere import CONSTANT, method


class Foo:
    CONSTANT = CONSTANT
    method = method

    def spam(self):
        ...

It should look up the value in globals() and assign it appropriately.
That's a bit less DRY, but if it's what you need, then you shouldn't
hesitate to use it.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/code-quality/attachments/20140208/df4e3ac8/attachment.html>


More information about the code-quality mailing list