Re: Decorating one method of a class C with another method of class C?
On 6/6/14, Ben Finney b...@benfinney.id.au wrote: Dan Stromberg drsali...@gmail.com writes: Is there a way of decorating method1 of class C using method2 of class C? Can you give a concrete example (i.e. not merely hypothetical) where this would be a useful feature (i.e. an actual improvement over the absence of the feature), and why? I have a class that's operating on a socket. I'd like to have simple operations on that socket like list configured hosts, allow connection to host, etc. And I'd like them to be decorated with reconnected_to_server_if_needed. I'll probably end up putting a try/except in each simple operation, making them a bit less simple. -- https://mail.python.org/mailman/listinfo/python-list
Re: Decorating one method of a class C with another method of class C?
On Mon, Jun 9, 2014 at 4:04 AM, Dan Stromberg drsali...@gmail.com wrote: I have a class that's operating on a socket. I'd like to have simple operations on that socket like list configured hosts, allow connection to host, etc. And I'd like them to be decorated with reconnected_to_server_if_needed. I'll probably end up putting a try/except in each simple operation, making them a bit less simple. Can you have the decorator outside the class, calling a regular method to do its main work? def recon_if_needed(f): def inner(self, *a, **kw): if self.disconnected: self.connect() return f(self, *a, **kw) return inner class SocketWorker: @recon_if_needed def send_packet(self, packet): assert not self.disconnected ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Decorating one method of a class C with another method of class C?
Dan Stromberg drsali...@gmail.com writes: I'd like to have simple operations on that socket like list configured hosts, allow connection to host, etc. And I'd like them to be decorated with reconnected_to_server_if_needed. The ‘reconnected_to_server_if_needed’ method, if I understand your original post correctly, does not need the class nor the class instance. So you can define that function outside the class, and use it for decorating methods within the class. -- \ “Teach a man to make fire, and he will be warm for a day. Set a | `\ man on fire, and he will be warm for the rest of his life.” | _o__) —John A. Hrastar | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Decorating one method of a class C with another method of class C?
Is there a way of decorating method1 of class C using method2 of class C? It seems like there's a chicken-and-the-egg problem; the class doesn't seem to know what self is until later in execution so there's apparently no way to specify @self.method2 when def'ing method1. -- https://mail.python.org/mailman/listinfo/python-list
Re: Decorating one method of a class C with another method of class C?
On Sat, Jun 7, 2014 at 10:14 AM, Dan Stromberg drsali...@gmail.com wrote: Is there a way of decorating method1 of class C using method2 of class C? It seems like there's a chicken-and-the-egg problem; the class doesn't seem to know what self is until later in execution so there's apparently no way to specify @self.method2 when def'ing method1. Since decoration happens at class creation, and arguments like self are available only when the method's actually called, no, there's no way you can define the method with something using information that doesn't exist yet and may change from one call to the next :) What are you trying to do, exactly? ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Decorating one method of a class C with another method of class C?
Dan Stromberg drsali...@gmail.com writes: Is there a way of decorating method1 of class C using method2 of class C? Can you give a concrete example (i.e. not merely hypothetical) where this would be a useful feature (i.e. an actual improvement over the absence of the feature), and why? It seems like there's a chicken-and-the-egg problem; the class doesn't seem to know what self is until later in execution so there's apparently no way to specify @self.method2 when def'ing method1. You're referring specifically to instance methods, it seems. Right, there's no instance *of* the class during the *definition* of the class, so ‘self’ can't refer to such an instance. Also, an instance method needs to get the instance as the first parameter, whereas the decorator must accept the to-be-decorated function as its argument. So I don't see what you're trying to achieve, rather than the more straightforward and clearer use of a decorator function which *isn't* a method in the same class. Can you show a Simple, Self-Contained Complete Example to show us what you're trying to do? More importantly, why you think it should be done this way? -- \“Visitors are expected to complain at the office between the | `\ hours of 9 and 11 a.m. daily.” —hotel, Athens | _o__) | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Re: Decorating one method of a class C with another method of class C?
On 6/6/2014 8:14 PM, Dan Stromberg wrote: Is there a way of decorating method1 of class C using method2 of class C? It seems like there's a chicken-and-the-egg problem; the class doesn't seem to know what self is until later in execution so there's apparently no way to specify @self.method2 when def'ing method1. Class code is executed in a new local namespace, which later becomes the class attribute space. So you can (sort of), but I cannot see a reason to do so. class C: def deco(f): print('decorating') def inner(self): print('f called') return f(self) return inner @deco def f(self): print(self) del deco # because it is not really a method # but rather an undecorated static method c = C() c.f() decorating f called __main__.C object at 0x0348B898 If deco is decorated as a staticmethod, it has to be called on the class or an instance thereof after the class is constructed. If deco is defined outside the class, it can be used both inside and outside. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: Decorating one method of a class C with another method of class C?
On Fri, 06 Jun 2014 17:14:54 -0700, Dan Stromberg wrote: Is there a way of decorating method1 of class C using method2 of class C? Yes. See below. It seems like there's a chicken-and-the-egg problem; the class doesn't seem to know what self is until later in execution so there's apparently no way to specify @self.method2 when def'ing method1. Directly inside the class statement, you don't need self. The class defines a namespace, like inside a function or globals, so you can just refer to names directly, like this: class Spam: def decorate(func): # Look Ma, no self! @functools.wraps(func) def inner(self, *args): print(self, args) return func(*args) return inner @decorate def method(self, a, b): return a+b That works fine for what you want to do. The disadvantage, however, is that if you call the decorate method from *outside* of the class scope (that is, from the outside like Spam.decorate, or inside a method like self.decorate) you'll run into some weird problems. Try it and see if you can diagnose the cause of the problem. This problem has a trivial, simple, obvious and wrong solution: ensure that the decorate method is a static method. That requires Spam to be a new-style class (inherit from object, or a built-in), but is otherwise trivial: class Spam(object): @staticmethod def decorate(func): # Look Ma, no self! ... Unfortunately, this does not work! staticmethod objects are not callable. It is only after you go through the descriptor protocol that you end up with something which is callable. Sad but true. That means that this will fail: class Spam(object): @staticmethod def decorate(func): ... @decorate # calling directly fails def method(self, args): ... but this will be okay: @Spam.decorate # calling via Spam or instance works def function(args): ... We're *so close* it hurts :-( Good news! staticmethod is a class, and like most classes we can subclass it and get the behaviour we want! # Untested class callablestaticmethod(staticmethod): def __call__(self, *args): return self.__func__(*args) ought to do it. Then just use callablestaticmethod instead of staticmethod, and all will be ginger-peachy. But what happens if you want the decorator to refer to the class itself? You can always hard-code references to Spam inside the decorate method, but a better solution may be to use a callableclassmethod instead. (Left as an exercise.) Inside the decorated method, or the wrapper method inner, we can refer to self as normal, and such references won't be evaluated until call- time when self exists. It's only inside the decorator itself, and the body of the class, that self doesn't yet exist. -- Steven D'Aprano http://import-that.dreamwidth.org/ -- https://mail.python.org/mailman/listinfo/python-list