Movatterモバイル変換


[0]ホーム

URL:


[Python-ideas] Define a method or function attribute outside of a class with the dot operator

Steven D'Apranosteve at pearwood.info
Mon Feb 13 20:48:15 EST 2017


On Fri, Feb 10, 2017 at 09:05:49PM -0500, Terry Reedy wrote:> >    def foo(self):> >        pass> >    Foo.foo = foo> >> >Becomes:> >> >    def Foo.foo(self):> >        pass>> Saving about 10 keystrokes is close to trivial.The same argument can be made for @decorator syntax.And, if I understand correctly, the same argument *was* made against decorator syntax: that it was trivial, unnecessary and confusing.In a realistic example, the function definition line:    def method(self, arg):and the line which actually injects it into the class:    MyClass.method = methodmay be separated by *many lines of code*. Yes, short methods are better than long methods, but even so, sometimes you have a long method. Arguably the most important part of the definition of this method (that it belongs to MyClass) may be lost way down the end, past the implementation.Just as with decorators, the current idiom for method injecting repeats the method name too many times:# the bad old way of using decoratorsdef function():    ...    ...    ...    ...function = decorator(function)# the nice clean way@decoratordef function():    ...    ...    ...    ...Likewise this proposal:# the bad current way repeats the method name at least three times:def method(self):    ...    ...    ...    ...MyClass.method = methoddel method# and for injecting into an instance, the instance twice:def method(self):    ...    ...    ...    ...instance.method = types.MethodType(method, instance)del method# the clean proposed way:def instance.method(self):  # or MyClass.method    ...    ...    ...    ...We can reasonably argue that the benefit is not worth the cost; we can even reasonably argue that we don't wish to encourage the Interceptor design pattern, method swizzling, extension methods or method injection, whatever name you want to call it. Even monkey-patching.But I don't think that we can reasonably argue that the suggested syntax isn't a clear, non-trivial win over the status quo, not unless we're also going to argue that introducing decorator syntax was a waste of time.> 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]Neither am I, but why would anyone write classes that way? Do you have evidence that people in the C#, VB, Objective-C, Swift or Lua communities routinely do that?> 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.Indeed. But in practice, I don't believe that two-phase initialization is the usual reason for using method injection. It seems to be more commonly used for "introspection, overriding default behavior, or maybe even dynamic method loading".https://blog.newrelic.com/2014/04/16/right-way-to-swizzle/-- Steve


More information about the Python-ideasmailing list

[8]ページ先頭

©2009-2026 Movatter.jp