0

I come from a C# background, so I'm using to seeing, fairly shortly after the class declaration, private member variables and properties. (My company follows StyleCop rules, which can be found here: Order of items in classes: Fields, Properties, Constructors, Methods).

I find this helpful, because you can see at a glance what the class comprises. It's almost like an implicit API documentation.

But in python, it seems to me that you can define self.something literally in any method, so to see what state your class can contain, you have to scroll through the entire class.

Is this how it's supposed to be done? Or is there a better way to structure my code?

butterflyknife
  • 1,438
  • 8
  • 17
  • 4
    How to organise a python class so that all member variables are near the top, step 1: Define all of its attributes in `__init__`. There is no step 2. – Aran-Fey Mar 05 '19 at 14:06
  • 1
    You could put init at the top. def __init__(self): self.varname=None self.varname2=None etc – Kenny Ostrom Mar 05 '19 at 14:07
  • 4
    Yes, in Python object members can generally be added at any point, and it is up to the developer to maintain a sane organzation so it is easy to read what the class is about. If you want to prevent dynamic addition of attributes you could use [`__slots__`](https://stackoverflow.com/questions/472000/usage-of-slots), although that has its own caveats and it is generally reserved for optimization purposes. – jdehesa Mar 05 '19 at 14:08
  • 2
    You might also want to take a look at the `dataclasses` module. – chepner Mar 05 '19 at 14:20
  • 1
    " it seems to me that you can define self.something literally in any method" => actually, you can define attributes just anywhere (except of course for slot-based types). But the good practice is indeed to define them all in the initializer (`__init__` method), that's what it's for. – bruno desthuilliers Mar 05 '19 at 14:28

1 Answers1

2

If your goal is to define all the member variables at the beginning of the class, as others have pointed out you need to put an init method right after the class declaration, like so:

class Foo:
    def __init__(self):
        self.bar = #whatever you want here
        self.baz = #again, whatever you want

If you are looking for style guidelines for python, check out PEP 8

  • I was looking for an hint in PEP 8 regarding this specific issue, but cannot find anything. Do you mind copying the adequate section here? – Dunatotatos Mar 05 '19 at 14:20
  • @Dunatotatos there's nothing in pep8 about this IIRC. – bruno desthuilliers Mar 05 '19 at 14:24
  • 1
    @Dunatotatos, bruno desthuilliers is right, I can't find anything in PEP8 about it, which I guess tells us that in python it really isn't that important in terms of style to define your member variables in a certain place. This makes sense I think, since python isn't really meant to have classes defined statically up front. You can add/remove class members dynamically, even from outside of the class. – jammertheprogrammer Mar 05 '19 at 14:31
  • I don't really understand why, in this case, pylint reports a warning `attribute-defined-outside-init` when defining a new attribute in method. But I guess this is an out-of-topic discussion. – Dunatotatos Mar 05 '19 at 15:07