[Python-ideas] Define a method or function attribute outside of a class with the dot operator
Terry Reedy
tjreedy at udel.edu
Fri Feb 10 21:05:49 EST 2017
On 2/10/2017 4:13 AM, Markus Meskanen wrote:
> I'm suggesting the addition of support to using a dot notation when
> defining a function to be a method of a class, or a callback attribute.
My default starting position for every proposed syntax addition is -1.
1. Additions usually make Python more complicated and harder to learn.
(This can be argued in particular cases.)
2. Syntax changes, when used, cut code off from past versions.
Consequently, to me, there should be a non-trivial gain to compensate
for the above.
> For example:
>
> def foo(self):
> pass
> Foo.foo = foo
>
> Becomes:
>
> def Foo.foo(self):
> pass
Saving about 10 keystrokes is close to trivial. If Foo is defined in
the same file, then putting the def in the class statement would save
even more. I am not enthusiastic about enablin the following style of
class definition.
class Foo: "Object that implement the Foo protocol.
def Foo.__init__(self, x):
self.x = s
def Foo.__getitem__(self, key):
return vars(Foo)[key]
...
> And when an object needs a callback as an attribute:
>
> class Menu:
> def __init__(self, items=None, select_callback=None):
> self.items = items if items is not None else []
> self.select_callback = select_callback
>
> my_menu = Menu([item1, item2])
>
> def my_menu.select_callback(self, item_index):
> print(self.items[item_index])
A function with a 'self' parameter is normally an instance method (a
function attribute of the class). As an instance attribute, it will
have be called as inst.select_callback(inst, index). But I suppose you
could find an example function that I like better as an instance attribute.
> As opposed to:
>
> my_menu = Menu([item1, item2])
>
> def select_callback(self, item_index):
> print(self.items[item_index])
> my_menu.select_callback = select_callback
or
my_menu.select_callback = (lambda self, item_index:
print(self.items[item_index]))
The problem with two-phase initialization is that one temporarily has a
partially initialized and likely useless object. I am not enthusiastic
about encouraging this.
> Or defining them in "unnatural" order:
To me, this is the natural and proper order: create all the objects
needed to initialize an instance before creating it. When __init__
returns, the instance is ready to go.
In tkinter programming, callbacks must be defined
before they are used in a bind or after call, which passes them on to
tk, where they are not directly accessible as attributes.
> def select_callback(self, item_index):
> print(self.items[item_index])
>
> my_menu = Menu([item1, item2], select_callback)
Looks good to me ;-)
--
Terry Jan Reedy
More information about the Python-ideas
mailing list