I think C# calls methods that are added to a class "extension methods". You can make a decorator that will do that for you:

> def extend(cls):
>     """
>     DECORATOR TO ADD METHODS TO CLASSES
>     :param cls: THE CLASS TO ADD THE METHOD TO
>     :return:
>     """
>     def extender(func):
>         setattr(cls, get_function_name(func), func)
>         return func
>     return extender

and use it

> C = MyClass
> @extend(C)
> def foo(self, schesome_param):
>     some_code()



On 2018-07-30 14:12, Chris Barker via Python-ideas wrote:
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
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.

 yup -- but you can still do a raw monkey-patch anyway. You asked for:

> Thank you for your question. You asked why not
>> c = MyClass
>> o = c()
>>
>> def c.foo(cls): ...

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









 
> 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.

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.


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
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/



--

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


_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/