Python, how to get the base instance instance?

In C #, I would go:

myObj.base 

I have a Date class that inherits from date.datetime. The Date class overrides __gt__() and __lt__() , so when using the < and > operators, they are called. I do not want to use these overrides - I want to use the date.datetime methods for the Date instance.

+4
source share
2 answers

Use super() to get a superclass object. Type help(super) at the Python command prompt.

From the manual:

 class super(object) | super(type) -> unbound super object | super(type, obj) -> bound super object; requires isinstance(obj, type) | super(type, type2) -> bound super object; requires issubclass(type2, type) | Typical use to call a cooperative superclass method: | class C(B): | def meth(self, arg): | super(C, self).meth(arg) 
+6
source

If I understand your question correctly, this does not make sense in Python. There is no "base instance" inside the subclass instance.

A Python instance is just one thing containing a set of attributes (any of which may have been set / modified by any of its base classes or indeed from code outside of any of its classes in general). Indeed, you can change the class of an instance at run time, even by transferring it to a completely different hereditary hierarchy (this is not often a good idea, but it is clearly defined). Regardless, the instance remains the only unitary object that knows only what attributes it has and what class the instance is (and in fact it is only an attribute: __class__ ).

Edit: If you want you to be able to call overridden methods on an instance, you do this using super , as hocl replied. However, from your comments, it seems that you are not completely bullying what super does (which is natural, since it is rather complicated).

super(Date, myObj) does not return a "base datetime.date " instance, because there is no such thing, only the myObj object. Although for your purposes this sounds like it will fill your needs (and you can probably stay with this sentence).

What he does is return - this is a magic wrapper around myObj that looks for methods that start only "behind" Date ; that is, it finds a method that will be called if Date does not override it. So in this case it will find all the methods from datetime.date , because you only have one inheritance going on.

The key difference is that it supports multiple inheritance. If someone makes another class that inherits from Date and also inherits from datetime.date different way, then super(Date, instanceOfThatClass) may not strike at datetime.date methods. It depends on the details of this hereditary hierarchy. Actually it was a super situation; it allowed classes in the complex hierarchy of multiple inheritance to interact with each other with the implementation, ensuring that each of them is called only once and in an order that is reasonable (although it may not be in the same order for each leaf leaf class, so the classes in in the middle, the hierarchy actually does not know which superclass implementation they call ). My understanding is that this difficult situation cannot occur in C #, so it can provide a simple .base syntax.

My understanding is also (and this is a little guess), because C # is statically typed and supports inheritance from classes defined in precompiled libraries, that if you have a Sub class inheriting from the Base class, there really is a full Base instance inside the Sub instance, which you can get and then call the methods. This will affect shady fields; I would expect (again, as a non-C # programmer to guess a bit) that after receiving a Base instance from a Sub instance, any direct link to the field overridden by Sub will remove the field from Base , not from Sub .

In Python, OTOH, there is no base instance, and classes cannot override fields. If the constructor and the Date and datetime.date methods both refer to the same field, it is just one field in the instance in which they are both shared. Therefore, using super will not change which field you get into, as you might expect, if you think of it as getting a base instance.

Given that you are not using a complex multiple inheritance situation, if you want a simple syntax, you can actually call Date.__lt__(myObj, otherObj) directly, although it looks ugly because you cannot use the infix operator syntax when you do this This is true. This is less terrible if you are considering conventional methods; in this case it is possibly simpler than using super .

Take a home message: I'm sure super(Date, myObj) is what you want in this case. But if you find yourself in more difficult situations, you do not want to think of super as a way to get a "base instance", as in C #. This understanding will entail you when you will be multiple inheritance (which may be too confusing anyway), but also when you have several levels in the inheritance hierarchy using the same field.

+3
source

Source: https://habr.com/ru/post/1384027/


All Articles