Re: Multiple inheritance and a broken super() chain
On Wed, 5 Jul 2023 at 10:31, Greg Ewing via Python-list wrote: > > On 5/07/23 10:33 am, Alan Gauld wrote: > > (*) C++ is the odd one out because it doesn't have GC, but then > > neither does it have an Object superclass so very often MI in C++ > > does not involve creating diamonds! And especially if the MI > > style is mixin based. > > Even if all your mixins have empty constructors, in C++ there > is still a diamond problem if they have any data members, because > you end up with multiple copies of them. > > But C++ has the concept of virtual base classes, which avoids the > diamond problem, albeit at the expense of making you explicitly > call all the base class constructors in your ancestry. Yeah, non-virtual MI in C++ is basically composition with a shorthand for calling non-conflicting methods or accessing non-conflicting data members. Point of random interest: Pike actually allows that sort of "composition MI" but will give you back an array of all parents when you seek a superclass's method, giving a very elegant syntax for MI. inherit Thing1; inherit Thing2; void method() { ::method(); //this is actually calling an array of two methods } Python's way of doing it requires that every class choose to cooperate in the MI and then be aware that they are all operating on the same object. Pike's and C++'s can sometimes be used as composition in disguise, but in general, MI does require proper cooperation. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Multiple inheritance and a broken super() chain
On 5/07/23 10:33 am, Alan Gauld wrote: (*) C++ is the odd one out because it doesn't have GC, but then neither does it have an Object superclass so very often MI in C++ does not involve creating diamonds! And especially if the MI style is mixin based. Even if all your mixins have empty constructors, in C++ there is still a diamond problem if they have any data members, because you end up with multiple copies of them. But C++ has the concept of virtual base classes, which avoids the diamond problem, albeit at the expense of making you explicitly call all the base class constructors in your ancestry. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Multiple inheritance and a broken super() chain
On Wed, 5 Jul 2023 at 08:35, Alan Gauld via Python-list wrote: > > On 03/07/2023 19:39, Chris Angelico via Python-list wrote: > > On Tue, 4 Jul 2023 at 03:39, Peter Slížik via Python-list > >> The legacy code I'm working with uses a classic diamond inheritance. > > > What happens when Top is initialized twice? This seems like a problem > > waiting to happen, and when you moved to using super(), you more than > > likely simplified things and fixed things. > > Slightly off topic but I wonder how many real world problems > people have experienced having the top of a diamond initialized > twice? The reason I ask is that I ran a maintenance team for > about 5 years (early 1990s) working on various OOP projects using MI; > in Lisp Flavors, C++(*) and a homebrew variant of C that supported MI. > In that time I don't recall ever having problems with top objects > being initialized twice (apart from redundant execution of code > of course). It's important to distinguish between diamond inheritance and what the OP seemed to expect, which was independent hierarchies. (In C++ terms, that's virtual inheritance and the unnamed default type of MI. Non-virtual inheritance??) With independent hierarchies, the object is composed of two subobjects, each with its own regular single-inheritance tree, and unless you need to call a method on the duplicated grandparent from the second parent (in which case you have to cast before calling), it's perfectly natural to treat them separately. But with virtual inheritance - as is always the case in Python - there is only one object. Whether it's a problem depends entirely on what the initializer does. If it's idempotent and doesn't depend on any arguments that it didn't already get, we're fine! But if it does something like this: class Example: def __init__(self): self.button = Some_GUI_Library.Button("Example") self.button.add_to_window() then calling init twice will create a second button. It's easy enough to design a specification that is safe against double initialization; but then, it's also not that hard to design a specification that's safe against super().__init__() and odd hierarchies. Since the OP didn't show us any of the code, I had to mention the possibility here. Of course, it's entirely possible that it isn't actually a problem. > In most cases the top object was so abstract that its init()/constructor > was only doing generic type stuff or opening database sessions/networks > etc which got lost and tidied up by garbage collectors. Remember though that diamond inheritance doesn't always happen at the top-level object. > So I'm curious about how big this "big problem with MI" is in > practice. I'm sure there are scenarios where it has bitten folks > but it never (or very rarely) occurred in our projects. (Of > course, being maintenance programmers, the problems may have > been ironed out before the code ever reached us! But that > wasn't usually the case...) Who said it's a big problem with MI? Diamond inheritance is in general a problem to be solved, but calling __init__ twice is a separate concern and usually only an issue when you try to treat MRO-based MI as if it were composition-based MI. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Multiple inheritance and a broken super() chain
On 03/07/2023 19:39, Chris Angelico via Python-list wrote: > On Tue, 4 Jul 2023 at 03:39, Peter Slížik via Python-list >> The legacy code I'm working with uses a classic diamond inheritance. > What happens when Top is initialized twice? This seems like a problem > waiting to happen, and when you moved to using super(), you more than > likely simplified things and fixed things. Slightly off topic but I wonder how many real world problems people have experienced having the top of a diamond initialized twice? The reason I ask is that I ran a maintenance team for about 5 years (early 1990s) working on various OOP projects using MI; in Lisp Flavors, C++(*) and a homebrew variant of C that supported MI. In that time I don't recall ever having problems with top objects being initialized twice (apart from redundant execution of code of course). In most cases the top object was so abstract that its init()/constructor was only doing generic type stuff or opening database sessions/networks etc which got lost and tidied up by garbage collectors. So I'm curious about how big this "big problem with MI" is in practice. I'm sure there are scenarios where it has bitten folks but it never (or very rarely) occurred in our projects. (Of course, being maintenance programmers, the problems may have been ironed out before the code ever reached us! But that wasn't usually the case...) (*) C++ is the odd one out because it doesn't have GC, but then neither does it have an Object superclass so very often MI in C++ does not involve creating diamonds! And especially if the MI style is mixin based. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos -- https://mail.python.org/mailman/listinfo/python-list
[Python-announce] Salabim 23.2.0 released
This is to announce the release of salabim 23.2.0 . Salabim is a discrete event simulation package that has applications in logistics, communications, production, mining, hospital operations, etc. It supports powerful realtime 2D and 3D animations, monitoring, statistical sampling functions, ... In contrast to SimPy, salabim is build around dynamic objects (components) that interact with each other. Up to now, that was done with generator functions (coroutines), like class Car(sim.Component): def process(self): yield self.hold(5) pump.activate() yield self.passivate() But as from this version, salabim processes can also run as greenlets, so yields are not required anymore: class Car(sim.Component): def process(self): self.hold(5) pump.activate() self.passivate() This makes modeling much more natural and less error prone. For more information, including the full documentation, changelog, etc. goto www.salabim.org . ___ Python-announce-list mailing list -- python-announce-list@python.org To unsubscribe send an email to python-announce-list-le...@python.org https://mail.python.org/mailman3/lists/python-announce-list.python.org/ Member address: arch...@mail-archive.com
[Python-announce] PyConZA 2023 - Second Call for Submissions
This is a second call for submissions to PyConZA 2023. PyConZA 2023 will take place on the 5th & 6th of October, 2023. This year, PyConZA will be a hybrid conference (with in-person and online access) hosted at the Premier Splendid Inn in Umhlanga, Durban. We are looking for the following presentations: - Keynotes (45 minute long talks on a subject of general interest) - Talks (30 minute long talks on more specific topics) - Remote Talks (30 minute long talks that will be delivered remotely - note that the number of remote talk slots is more limited due to technical constraints). If you would like to give a presentation, please register at https://za.pycon.org/ and submit your proposal, following the instructions at https://za.pycon.org/talks/how-to-submit-a-talk/ . We have a number of tracks available, including: Data Science, Teaching and Learning with Python, Web, Scientific Computing, Testing and Other (which includes all talks that don't fall under the mentioned tracks). We hope to notify accepted presenters by no later than the 31st of August 2023. Speakers will be expected to be available after the presentation for a short Q session. Shared sessions are also possible. The presentations will be in English. PyConZA offers a mentorship program for inexperienced speakers. If you would like assistance preparing your submission, email t...@za.pycon.org with a rough draft of your talk proposal and we'll find a suitable experienced speaker to act as a mentor. If you want to present something that doesn't fit into the standard talk categories at PyConZA, please contact the organising committee at t...@za.pycon.org so we can discuss whether that will be feasible -- Neil Muller On behalf of the PyConZA organising committee ___ Python-announce-list mailing list -- python-announce-list@python.org To unsubscribe send an email to python-announce-list-le...@python.org https://mail.python.org/mailman3/lists/python-announce-list.python.org/ Member address: arch...@mail-archive.com
Best practices for using super()
As a follow-up to my yesterday's question - are there any recommendations on the usage of super()? It's clear that super() can be used to invoke parent's: - instance methods - static methods - constants ("static" attributes in the parent class, e.g. super().NUMBER). This all works, but are there situations in which calling them explicitly using a parent class name is preferred? Best regards, Peter -- https://mail.python.org/mailman/listinfo/python-list
Re: Multiple inheritance and a broken super() chain
On Tue, 4 Jul 2023 at 22:06, Peter Slížik via Python-list wrote: > > > > > Also, you might find that because of the MRO, super() in your Bottom > > class would actually give you what you want. > > > > I knew this, but I wanted to save myself some refactoring, as the legacy > code used different signatures for Left.__init__() and Right.__init__(). This sounds like a mess that I would not touch. Unless something needs to be fixed, I wouldn't switch these to use super() - I'd leave them using explicit parent calls. However, I would acknowledge somewhere that this will cause Top.__init__() to be called twice on the same object. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Multiple inheritance and a broken super() chain
> > Also, you might find that because of the MRO, super() in your Bottom > class would actually give you what you want. > I knew this, but I wanted to save myself some refactoring, as the legacy code used different signatures for Left.__init__() and Right.__init__(). I realized the formatting of my code examples was completely removed; sorry for that. Best regards, Peter -- https://mail.python.org/mailman/listinfo/python-list