Python 3 object construction: which is the most Pythonic / the accepted way?

纵然是瞬间 提交于 2019-12-03 07:01:07

The first you describe is very common. Some use the shorter

class Foo:
   def __init__(self, foo, bar):
       self.foo, self.bar = foo, bar

Your second approach isn't common, but a similar version is this:

class Thing:
   def __init__(self, **kwargs):
       self.something = kwargs['something']
       #..

which allows to create objects like

t = Thing(something=1)

This can be further modified to

class Thing:
   def __init__(self, **kwargs):
       self.__dict__.update(kwargs)

allowing

t = Thing(a=1, b=2, c=3)
print t.a, t.b, t.c # prints 1, 2, 3

As Debilski points out in the comments, the last method is a bit unsafe, you can add a list of accepted parameters like this:

class Thing:
    keywords = 'foo', 'bar', 'snafu', 'fnord'
    def __init__(self, **kwargs):
        for kw in self.keywords:
            setattr(self, kw, kwargs[kw])

There are many variations, there is no common standard that I am aware of.

I’ve not seen many of your field_maps in real life. I think that would only make sense if you were to use the field_map at some other place in your code as well.

Concerning your third example: Even though you don’t need to assign to them (other than None), it is common practice to explicitly declare attributes in the __init__ method, so you’ll easily see what properties your object has.

So the following is better than simply having an empty __init__ method (you’ll also get a higher pylint score for that):

class Blah(object):
    def __init__(self):
        self.foo = None
        self.bar = None

blah = Blah()
blah.foo = var1

The problem with this approach is, that your object might be in a not well-defined state after initialisation, because you have not yet defined all of your object’s properties. This depends on your object’s logic (logic in code and in meaning) and how your object works. If it is the case however, I’d advise you not to do it this way. If your object relies on foo and bar to be meaningfully defined, you should really put them inside of your __init__ method.

If, however, the properties foo and bar are not mandatory, you’re free to define them afterwards.

If readability of the argument lists is an issue for you: Use keyword arguments.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!