Re: super() is super [was Re: Calling dunder methods manually]

2017-04-15 Thread Gregory Ewing

Steve D'Aprano wrote:

But for the simple cases, using super() in Python 3 couldn't be easier.


The only "simple" use of super() is in the single inheritance
case. But that's also the case where it gains you the least
over an explicit inherited method call.


If you have multiple inheritance, and don't use super(), then your code is
buggy, whether you have realised it or not.

Manually calling your parent class is only acceptable if you can absolutely
guarantee that your class, all its parent classes, and all its subclasses
will ONLY use single inheritance.


I don't agree with that at all. It's quite possible to write
code that uses multiple inheritance, doesn't use super() and
works perfectly correctly.

Someone else might use my class in an inheritance network in
a way that results in misbehaviour, but if it happens, *they*
wrote that bug, not me.

You could argue that I *should* write my code so that anyone
can mix it with anything in any way without having to think
about the consequences, but that sounds more like a moral
judgement than a technical argument.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: super() is super [was Re: Calling dunder methods manually]

2017-04-15 Thread Chris Angelico
On Sun, Apr 16, 2017 at 10:35 AM, Steve D'Aprano
 wrote:
>
>> eaisier to just write the path in long-form.
>
> Easier and wrong.
>
> If you have multiple inheritance, and don't use super(), then your code is
> buggy, whether you have realised it or not.
>
> Manually calling your parent class is only acceptable if you can absolutely
> guarantee that your class, all its parent classes, and all its subclasses
> will ONLY use single inheritance.

Plus, it's fragile in that it names the parent class everywhere.

class A:
def __init__(self): ...
def __add__(self, other): ...
def __or__(self, other): ...

class B(A):
def __init__(self):
A.__init__(self)
def __add__(self, other):
A.__add__(self, other)
...

Every method you subclass-and-call-parent needs to say the name of the
parent class. With super, they all just say super(). I know which one
I'd rather do.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


super() is super [was Re: Calling dunder methods manually]

2017-04-15 Thread Steve D'Aprano
On Sat, 15 Apr 2017 10:50 pm, Rick Johnson wrote:

> Even to this day, i avoid super because the
> semantics are confusing, 

If super() is confusing, it is because *inheritance* is confusing, and that
goes triple for multiple inheritance. If it is not *easy* to use super() to
manage your class' inheritance, that's a sign that your class hierarchy is
complicated and confusing and you're in a nightmare whether you use super()
or not.

But for the simple cases, using super() in Python 3 couldn't be easier. If
you have code that looks something like this:


class MyClass(ParentClass):
def method(self, arg):
result = ParentClass.method(self, arg)


you replace the last line with:

result = super().method(arg)


If you have:

class MyClass(A, B):
def method(self, arg):
A.method(self, arg)
B.method(self, arg)


you replace the last two lines with:

super().method(arg)


See also:

https://rhettinger.wordpress.com/2011/05/26/super-considered-super/



> eaisier to just write the path in long-form.

Easier and wrong.

If you have multiple inheritance, and don't use super(), then your code is
buggy, whether you have realised it or not.

Manually calling your parent class is only acceptable if you can absolutely
guarantee that your class, all its parent classes, and all its subclasses
will ONLY use single inheritance.





-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Calling dunder methods manually

2017-04-15 Thread Rick Johnson
On Thursday, April 13, 2017 at 2:01:41 AM UTC-5, Serhiy Storchaka wrote:
>
> __init__ is perhaps the most called dunder method. It is
> often called from the __init__ method of subclasses.

Yes, that would be one of the exceptions to the rule, but
not because the rule is unsound, but because Python's super
really sucks. Even to this day, i avoid super because the
semantics are confusing, eaisier to just write the path in
long-form. In many other languages though, super is
intelligent enough to know what scope it is in. But in any
event, i cannot think one one good reason to call dunder
methods from outside a class definition (maybe someone can
think of a few???).

> __add__ also can be called from other __add__, __iadd__ or
> __radd__.

Some people have mentioned using the methods of the operator
module to avoid calling dunders, but from the POV of
consistency, i think such a policy would be a bad idea and
just more evidence that Python's super is woefully
inadequate.

Which begs the question: "What's the point of having super
if the majority are unwilling to use it?" Hmm. I suppose
"for consistency's sake" would be the only legitimate
answer.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Calling dunder methods manually

2017-04-13 Thread eryk sun
On Thu, Apr 13, 2017 at 8:24 AM, Chris Warrick  wrote:
> On 13 April 2017 at 09:43, eryk sun  wrote:
>> The functions in the operator module implement abstract behavior (e.g.
>> PyNumber_Add in CPython):
>>
>> >>> operator.__add__(C(), D())
>> 42
>
> Those functions also do not need underscores — operator.add is a
> prettier way to achieve the same result.

I debated myself about which one to use in the example. The dunder
aliases were added for completeness, to clarify the relationship to
the corresponding special method, and I suppose to make it simpler to
dynamically call them. I opted to use the explicit name, even though
it's an alias because it seemed to make the example more consistent.
Normally I would call operator.add.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Calling dunder methods manually

2017-04-13 Thread Chris Angelico
On Thu, Apr 13, 2017 at 4:18 PM, Rustom Mody  wrote:
> I believe it was ChrisA who gave a pithy summary of the situation:
> Dont CALL dunders
> But its fine to DEFINE them

As others have mentioned, you call dunders during the definitions of
dunders, mainly during subclassing. But from outside the class, you
generally shouldn't.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Calling dunder methods manually

2017-04-13 Thread Chris Warrick
On 13 April 2017 at 09:43, eryk sun  wrote:
> The functions in the operator module implement abstract behavior (e.g.
> PyNumber_Add in CPython):
>
> >>> operator.__add__(C(), D())
> 42

Those functions also do not need underscores — operator.add is a
prettier way to achieve the same result.

-- 
Chris Warrick 
PGP: 5EAAEA16
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Calling dunder methods manually

2017-04-13 Thread eryk sun
On Thu, Apr 13, 2017 at 5:29 AM, Steven D'Aprano  wrote:
>
> my_number.__add__(another_number)
>
> The short answer is:
>
> NO! In general, you shouldn't do it.

For example:

class C:
def __add__(self, other):
return NotImplemented

class D:
def __radd__(self, other):
return 42

>>> C().__add__(D())
NotImplemented

>>> C() + D()
42

The functions in the operator module implement abstract behavior (e.g.
PyNumber_Add in CPython):

>>> operator.__add__(C(), D())
42
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Calling dunder methods manually

2017-04-13 Thread eryk sun
On Thu, Apr 13, 2017 at 5:29 AM, Steven D'Aprano  wrote:
> Should you call dunder methods (Double leading and trailing UNDERscores)
> manually? For example:
>
>
> my_number.__add__(another_number)
>
>
> The short answer is:
>
> NO! In general, you shouldn't do it.
>
>
> Guido recently commented:
>
> I agree that one shouldn't call __init__ manually (and in fact Python
> always reserves the right to have "undefined" behavior when you
> define or use dunder names other than documented).
>
>
> so unless documented as safe to use manually, you should assume that it
> is not.
>
>
> https://github.com/python/typing/issues/241#issuecomment-292694838

I manually call dunder methods all the time when overriding a special
method in a subclass. It's happening all over the place -- thousands
and even millions of times in a program. You generally shouldn't call
them outside of a class definition -- not because it's inherently bad
(though calling __init__ on an already initialized object is weird and
probably bad), but because it's bad style and does an end-run around
the high-level behavior of the interpreter.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Calling dunder methods manually

2017-04-13 Thread Serhiy Storchaka

On 13.04.17 08:29, Steven D'Aprano wrote:

Should you call dunder methods (Double leading and trailing UNDERscores)
manually? For example:


my_number.__add__(another_number)


The short answer is:

NO! In general, you shouldn't do it.


Guido recently commented:

I agree that one shouldn't call __init__ manually (and in fact Python
always reserves the right to have "undefined" behavior when you
define or use dunder names other than documented).


so unless documented as safe to use manually, you should assume that it
is not.


https://github.com/python/typing/issues/241#issuecomment-292694838


__init__ is perhaps the most called dunder method. It is often called 
from the __init__ method of subclasses.


__add__ also can be called from other __add__, __iadd__ or __radd__.

--
https://mail.python.org/mailman/listinfo/python-list


Re: Calling dunder methods manually

2017-04-13 Thread Rustom Mody
On Thursday, April 13, 2017 at 11:00:03 AM UTC+5:30, Steven D'Aprano wrote:
> Should you call dunder methods (Double leading and trailing UNDERscores) 
> manually? For example:
> 
> 
> my_number.__add__(another_number)
> 
> 
> The short answer is:
> 
> NO! In general, you shouldn't do it.
> 
> 
> Guido recently commented:
> 
> I agree that one shouldn't call __init__ manually (and in fact Python
> always reserves the right to have "undefined" behavior when you
> define or use dunder names other than documented).
> 
> 
> so unless documented as safe to use manually, you should assume that it 
> is not.
> 
> 
> https://github.com/python/typing/issues/241#issuecomment-292694838
> 
> 
> 
> This-Public-Service-Announcement-Brought-To-You-By-MyPy-ly y'rs,
> 
> 
> 
> 
> -- 
> Steve

I believe it was ChrisA who gave a pithy summary of the situation:
Dont CALL dunders
But its fine to DEFINE them
-- 
https://mail.python.org/mailman/listinfo/python-list


Calling dunder methods manually

2017-04-12 Thread Steven D'Aprano
Should you call dunder methods (Double leading and trailing UNDERscores) 
manually? For example:


my_number.__add__(another_number)


The short answer is:

NO! In general, you shouldn't do it.


Guido recently commented:

I agree that one shouldn't call __init__ manually (and in fact Python
always reserves the right to have "undefined" behavior when you
define or use dunder names other than documented).


so unless documented as safe to use manually, you should assume that it 
is not.


https://github.com/python/typing/issues/241#issuecomment-292694838



This-Public-Service-Announcement-Brought-To-You-By-MyPy-ly y'rs,




-- 
Steve
-- 
https://mail.python.org/mailman/listinfo/python-list