Wield Python's super() like a Jedi
31–40 of 67 posts
Re: Wield Python's super() like a Jedi
#32Nice article, but one thing struck me when reading the code examples posted in the article: What's the use of using kwds in __init__? class Shape(Root): def __init__(self, **kwds): self.shapename = kwds.pop('shapename') super().__init__(**kwds) class ColoredShape(Shape): def __init__(self, **kwds): self.color = kwds.pop('color') super().__init__(**kwds) I would personally just have written this somewhat similar to th…
Thus, ColoredShape.__init__ can't simply pass on shapename to the super method, because that might not be the argument expected by the next __init__ method in the MRO. Instead, each method needs to gracefully accept arbitrary arguments and then pass on whatever it received (minus what it consumed).
Re: Wield Python's super() like a Jedi
#33It seems to me that code that uses super() in these creative ways will be very difficult to maintain. You need to understand the subtleties of the MRO just to find out which method is being called. Pitty the poor Python programmer who stumbles into such code without being aware that super() may not call the class's direct base. I suppose similar criticism can be leveled against many other dynamic techniques, except t…
I think in a case like the one you describe, where the direct ancestor's implementation is circumvented to access a different ancestor's implementation, it should be done by calling
super(Ancestor).someMethod()
That should improve understanding.Re: Wield Python's super() like a Jedi
#34It seems to me that code that uses super() in these creative ways will be very difficult to maintain. You need to understand the subtleties of the MRO just to find out which method is being called. Pitty the poor Python programmer who stumbles into such code without being aware that super() may not call the class's direct base. I suppose similar criticism can be leveled against many other dynamic techniques, except t…
super() supports arguments which allow you to specify which class's implementation to lookup, which is an explicit way to resolve ambiguities. Although well-designed multiple-inheritance should try to avoid those ambiguities in the first place -- a class shouldn't inherit from multiple bases with conflicting implementations of a method. I think in a case like the one you describe, where the direct ancestor's implemen…
Re: Wield Python's super() like a Jedi
#35Have to deal with enough languages as it is. Don't want to further add to my brain mess by learning Python 3 syntax just yet.
Python 3 was introduced two and a half years ago. Its major syntactic changes, while frustrating if you're set in your ways, are hardly insurmountable.
Re: Wield Python's super() like a Jedi
#36Personally I'm not in favor of enforcing such strict conventions, especially in a dynamic language like Python. Also isn't this pattern he repeats throughout: class Shape: def __init__(self, **kwds): self.shapename = kwds.pop('shapename') super().__init__(**kwds) Better written like this? class Shape: def __init__(self, shapename=None, **kwds): self.shapename = shapename super().__init__(**kwds) It seems like there a…
In [1]: def init(shapename=None, **kwargs):
...: pass
...:
In [2]: init(shapename='circle', **{'shapename': 'circle'})
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/teh/Desktop/ in ()
TypeError: init() got multiple values for keyword argument 'shapename'Re: Wield Python's super() like a Jedi
#37Personally I'm not in favor of enforcing such strict conventions, especially in a dynamic language like Python. Also isn't this pattern he repeats throughout: class Shape: def __init__(self, **kwds): self.shapename = kwds.pop('shapename') super().__init__(**kwds) Better written like this? class Shape: def __init__(self, shapename=None, **kwds): self.shapename = shapename super().__init__(**kwds) It seems like there a…
The issue with your second version is In [1]: def init(shapename=None, **kwargs): ...: pass ...: In [2]: init(shapename='circle', **{'shapename': 'circle'}) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) /home/teh/Desktop/ in () TypeError: init() got multiple values for keyword argument 'shapename'
>>> def init(**kwargs):
... pass
...
>>> init(shapename='circle', **{'shapename': 'circle'})
Traceback (most recent call last):
File "", line 1, in
TypeError: init() got multiple values for keyword argument 'shapename'Re: Wield Python's super() like a Jedi
#38Re: Wield Python's super() like a Jedi
#39Earlier quoted context omitted.
super() supports arguments which allow you to specify which class's implementation to lookup, which is an explicit way to resolve ambiguities. Although well-designed multiple-inheritance should try to avoid those ambiguities in the first place -- a class shouldn't inherit from multiple bases with conflicting implementations of a method. I think in a case like the one you describe, where the direct ancestor's implemen…
I disagree, that's extremely fragile. It might work for the particular class you are implementing. However, it might cause subclasses of that class to break, since those subclasses will have a different MRO than the current class, and you could end up skipping more of the MRO than you intended.
Re: Wield Python's super() like a Jedi
#40Earlier quoted context omitted.
super() supports arguments which allow you to specify which class's implementation to lookup, which is an explicit way to resolve ambiguities. Although well-designed multiple-inheritance should try to avoid those ambiguities in the first place -- a class shouldn't inherit from multiple bases with conflicting implementations of a method. I think in a case like the one you describe, where the direct ancestor's implemen…
I disagree, that's extremely fragile. It might work for the particular class you are implementing. However, it might cause subclasses of that class to break, since those subclasses will have a different MRO than the current class, and you could end up skipping more of the MRO than you intended.