On 3/1/2016 12:24 PM, ast wrote:
Hello
It's not clear to me what arguments are passed to the
__new__ method.
The objects passed to any function are the objects that are passed. The
type and number of objects that *should be* passed depends on the
signature of the function.
If class C defines __new__, then C.__new__ will receive as args C and
all args passed in a C(...) call. So the C(...) call should have args
that match those expected by __new__. If C also defines __init__, it
will get the same args other than self replacing cls and thus it should
have the same signature.
The case is covered by in the entry for __new__ in
https://docs.python.org/3/reference/datamodel.html#basic-customization
"If __new__() returns an instance of cls, then the new instance’s
__init__() method will be invoked like __init__(self[, ...]), where self
is the new instance and the remaining arguments are the same as were
passed to __new__()."
class Premiere:
def __new__(cls, price):
return object.__new__(cls)
This matches "Typical implementations create a new instance of the class
by invoking the superclass’s __new__() method using super(currentclass,
cls).__new__(cls[, ...]) with appropriate arguments and then modifying
the newly-created instance as necessary before returning it."
object.__new__ only takes the cls parameter.
def __init__(self, price):
pass
p = Premiere(1000)
No errors, so it seems that 2 arguments are passed
to __new__, cls and price,
and 2 arguments are passed to __init__, self and price -- as documented.
But if i do:
class Premiere:
def __new__(cls, price):
return object.__new__(cls, price)
You get an error in current python because you sent an extra arg to
object.__new__. If __new__ calls a superclass __new__, then it should
only pass the args expected. At one time, object.__new__ would have
accepted the price arg and ignored it. This is no longer true
def __init__(self, price):
pass
p = Premiere(1000)
it fails. It is strange because according to me it is equivalent to:
Well, 'you' is wrong ;-), because in the following case,
Premiere.__new__ is object.__new__, which has a different signature than
__new__ above.
class Premiere:
def __init__(self, price):
pass
p = Premiere(1000)
which is OK.
Premiere is callable because it inherits object.__call__. That
function, or the implementation of the CALL FUNCTION bytecode, must
notice that Premiere.__new__ is object.__new__, by inheritance, and only
pass Premiere and not 1000.
The doc entry for __init__ says "The arguments are those passed to the
class constructor expression." (The latter is the expression in the
code that results in the class call.) This is always true. But since
the signature of object.__new__ was restricted, the claim that the same
args are sent to __new__ and __init__ seems not to be true.
I may open a new doc issue.
--
Terry Jan Reedy
--
https://mail.python.org/mailman/listinfo/python-list