
Hi all, Not sure if this subject has been brought up already, but why can't we redefine methods as such for example: c = MyClass o = c() def c.foo(cls): ... def o.bar(self): ... Thanks in advance for sharing some of your insight -- ∞

Hi Jamesie Thank you for your question. You asked why not
I've the same same query, but never had the courage to ask. So that you for asking. And also giving me a chance to share my thoughts. In Ruby, I believe, you can 'open up' an existing class, and add new methods to it. You can even do with core classes. I think what you asking might amount to a wish to do the same in Python. I think the Python way to 'open up' an existing class is to create a subclass, and add methods to that. Python design and development is quite pragmatic. So instead of us saying why it's not there, why don't you tell why you think it might be good idea. Based of course on examples. Particularly code taken from successful real-world applications. By the way, your
It's perhaps a bit technical and short of examples, but https://docs.python.org/3/reference/datamodel.html would be a good starting point. Can anyone else recommend some other URLs for this. Once again, thank you for asking this question. I look forward to reading other answers (and of course your response). -- Jonathan

On 31 July 2018 at 01:35, Jonathan Fine <jfine2358@gmail.com> wrote:
It's essentially due to the fact that while we deliberately allow runtime monkeypatching (as it's sometimes the best available answer), we also strongly encourage the idea of treating it as a last resort option (outside specific use cases like testing). So if you want to define methods on a class, the strongly preferred place to define them is inside the class definition, where they're easy for future maintainers of that class to find. If you need to replace them for some reason, it will preferably be within a temporary bounded scope, using a tool like unittest.mock.patch, rather than as a permanent change that affects every other use of the class within the process. Cheers, Nick. P.S. While it's *not* explicitly part of Python's design rationale, http://connascence.io/locality.html and the rest of that site provide some good info on the kinds of problems that "action at a distance" effects, like monkeypatching class definitions, can cause in a code base. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Mon, Jul 30, 2018 at 9:10 AM, Nick Coghlan <ncoghlan@gmail.com> wrote: If you need to replace them for some reason, it will preferably be
yup -- but you can still do a raw monkey-patch anyway. You asked for:
do you mean this? you want a classmethod? or is this what you mean? -- which you can do: C = MyClass def foo(self, some_param): some_code() C.foo = foo (note that I used a capital C -- capitalized names are traditional for classes -- see PEP 8) In that case, any existing, and new instances of the C class will now have the foo method. Also -- that line: C = MyClass -- binds the name "C" to the very same class object as MyClass -- so you will have just monkey=patched MyClass -- I"m guessing you didn't want that. If not, and you wanted C t be a copy of MyClass that you could then change/add/remove methods from, then you want subclassing -- that is exactly what it is for. Then there is this:
def o.bar(self): ...
which is monkey patching an instance object, which you can also do, but you don't get a bound method -- i.e. it doesn't get self passed in automatically. -CHB
-- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov

I like type() a lot, and the attributes dict it takes as argument works with lambda. My use case is just a python module for a framework provides a default instance for some model, and I thought it would be cool to just change a method without going through I'm really bad at defending ideas, specially in English, but I have one statement to try: How exciting is life if you're not monkey patching runtime on a daily basis ? Cheers

Sorry if my message offended anyone (noted that the "Toxic Forum" post came not long after mine). What I meant is that I cannot defend such an idea before extensively using it. I just don't know how to do it this way. Have a great day

Jamesie Pic wrote:
def o.bar(self): ...
You could get almost the same effect with from functools import partial def bar(self, other_args): ... o.bar = partial(bar, o) But IMO this is nowhere near being a common enough thing to do to justify having special syntax for it. -- Greg

On Tue, Jul 31, 2018 at 10:10:32AM +1200, Greg Ewing wrote:
Why are you using functools.partial instead of types.MethodType? I'm wondering if there is some advantage to partial that I don't recognise. I'm not sure if there's a functional difference between the two approaches, but it makes o.bar a different kind of callable and that will probably make a difference to somebody.
But IMO this is nowhere near being a common enough thing to do to justify having special syntax for it.
This sort of thing isn't common because there's no neat, easy, obvious, built-in way to do it. If we allowed people to extend classes using the syntax def classobj.methodname(...): ... def instance.methodname(...): ... people would use the technique more. For good or ill. I don't question the utility of this technique, but I suspect we prefer to *slightly* discourage it by *not* providing a Batteries Included solution for this. If you want to do this, we won't stop you, but neither will we encourage it by supporting it in syntax or providing a standard decorator for it. -- Steve

Here is an example of how it could be done. https://gist.github.com/stephanh42/97b47506e5e416f97f5790c070be7878 Stephan Op di 31 jul. 2018 01:29 schreef Steven D'Aprano <steve@pearwood.info>:

Hi Jamesie Thank you for your question. You asked why not
I've the same same query, but never had the courage to ask. So that you for asking. And also giving me a chance to share my thoughts. In Ruby, I believe, you can 'open up' an existing class, and add new methods to it. You can even do with core classes. I think what you asking might amount to a wish to do the same in Python. I think the Python way to 'open up' an existing class is to create a subclass, and add methods to that. Python design and development is quite pragmatic. So instead of us saying why it's not there, why don't you tell why you think it might be good idea. Based of course on examples. Particularly code taken from successful real-world applications. By the way, your
It's perhaps a bit technical and short of examples, but https://docs.python.org/3/reference/datamodel.html would be a good starting point. Can anyone else recommend some other URLs for this. Once again, thank you for asking this question. I look forward to reading other answers (and of course your response). -- Jonathan

On 31 July 2018 at 01:35, Jonathan Fine <jfine2358@gmail.com> wrote:
It's essentially due to the fact that while we deliberately allow runtime monkeypatching (as it's sometimes the best available answer), we also strongly encourage the idea of treating it as a last resort option (outside specific use cases like testing). So if you want to define methods on a class, the strongly preferred place to define them is inside the class definition, where they're easy for future maintainers of that class to find. If you need to replace them for some reason, it will preferably be within a temporary bounded scope, using a tool like unittest.mock.patch, rather than as a permanent change that affects every other use of the class within the process. Cheers, Nick. P.S. While it's *not* explicitly part of Python's design rationale, http://connascence.io/locality.html and the rest of that site provide some good info on the kinds of problems that "action at a distance" effects, like monkeypatching class definitions, can cause in a code base. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Mon, Jul 30, 2018 at 9:10 AM, Nick Coghlan <ncoghlan@gmail.com> wrote: If you need to replace them for some reason, it will preferably be
yup -- but you can still do a raw monkey-patch anyway. You asked for:
do you mean this? you want a classmethod? or is this what you mean? -- which you can do: C = MyClass def foo(self, some_param): some_code() C.foo = foo (note that I used a capital C -- capitalized names are traditional for classes -- see PEP 8) In that case, any existing, and new instances of the C class will now have the foo method. Also -- that line: C = MyClass -- binds the name "C" to the very same class object as MyClass -- so you will have just monkey=patched MyClass -- I"m guessing you didn't want that. If not, and you wanted C t be a copy of MyClass that you could then change/add/remove methods from, then you want subclassing -- that is exactly what it is for. Then there is this:
def o.bar(self): ...
which is monkey patching an instance object, which you can also do, but you don't get a bound method -- i.e. it doesn't get self passed in automatically. -CHB
-- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov

I like type() a lot, and the attributes dict it takes as argument works with lambda. My use case is just a python module for a framework provides a default instance for some model, and I thought it would be cool to just change a method without going through I'm really bad at defending ideas, specially in English, but I have one statement to try: How exciting is life if you're not monkey patching runtime on a daily basis ? Cheers

Sorry if my message offended anyone (noted that the "Toxic Forum" post came not long after mine). What I meant is that I cannot defend such an idea before extensively using it. I just don't know how to do it this way. Have a great day

Jamesie Pic wrote:
def o.bar(self): ...
You could get almost the same effect with from functools import partial def bar(self, other_args): ... o.bar = partial(bar, o) But IMO this is nowhere near being a common enough thing to do to justify having special syntax for it. -- Greg

On Tue, Jul 31, 2018 at 10:10:32AM +1200, Greg Ewing wrote:
Why are you using functools.partial instead of types.MethodType? I'm wondering if there is some advantage to partial that I don't recognise. I'm not sure if there's a functional difference between the two approaches, but it makes o.bar a different kind of callable and that will probably make a difference to somebody.
But IMO this is nowhere near being a common enough thing to do to justify having special syntax for it.
This sort of thing isn't common because there's no neat, easy, obvious, built-in way to do it. If we allowed people to extend classes using the syntax def classobj.methodname(...): ... def instance.methodname(...): ... people would use the technique more. For good or ill. I don't question the utility of this technique, but I suspect we prefer to *slightly* discourage it by *not* providing a Batteries Included solution for this. If you want to do this, we won't stop you, but neither will we encourage it by supporting it in syntax or providing a standard decorator for it. -- Steve

Here is an example of how it could be done. https://gist.github.com/stephanh42/97b47506e5e416f97f5790c070be7878 Stephan Op di 31 jul. 2018 01:29 schreef Steven D'Aprano <steve@pearwood.info>:
participants (8)
-
Chris Barker
-
Greg Ewing
-
Jamesie Pic
-
Jonathan Fine
-
Kyle Lahnakoski
-
Nick Coghlan
-
Stephan Houben
-
Steven D'Aprano