Python: Why would float.__new__(cls) work when cls isn't float?

后端 未结 2 1146
暗喜
暗喜 2021-01-25 07:26

I\'m a little confused by the following example from the python documentation here.

>>> class inch(float):
...     \"Convert from inch to meter\"
...            


        
2条回答
  •  隐瞒了意图╮
    2021-01-25 08:08

    Because inch is a subclass of float, it satisfies all the requirements that the float.__new__() instance factory has. It is the job of the __new__(cls) static method to create instances of the first argument, not of it's 'own' class.

    Note the word 'static method' there. The __new__ factory is really just a specialist function tied to a class only for inheritance reasons. In other words, it is a function that plays well in a object-oriented hierarchy. You are supposed to find it via super() or perhaps call it directly (as done here). The following would actually be a little more pythonic:

    def __new__(cls, arg=0.0):
        return super(inch, cls).__new__(cls, arg*0.0254)
    

    because that would call the 'correct' __new__ function if inch were to be used in a multiple-inheritance hierarchy; in this simple example it'll end up calling float.__new__ just the same.

    So, __new__(cls, ...) is expected to create an instance of type cls. Why then tie it to a class at all and not make it a more generic function then? Because in the case of float.__new__(cls, value) it not only creates a new instance of type cls, it also sets it's initial value to value. And in order for that to work, float.__new__(...) needs to have intimate knowledge of what the float class looks like. Because inch() is a subclass of float(), it has the exact same necessary bits to be a float() too, and thus when the float.__new__() factory creates a new inch instance, all those bits are there to make it a inch() instance instead.

提交回复
热议问题