Thanks for letting me know and cheers for the comment—I indeed spent a bit
of time to follow the Python standards in the hope that it would be a good
enough coding example for the beginners willing to write libraries.
As written in the final note of the article, in Maya 2010 PyMEL wasn't
shipped and I was left with either using the MEL/Python commands layer
which from a coder standpoing I find to be a real abomination to use, or
the Maya Python API.
The good thing with the Maya Python API is that it's not a jungle of
nonsensical global functions each spammed with tons of flags that are often
incompatible with each other like the MEL/Python commands layer is. At
least things the methods from the API are logically organised like with any
OO library, so that's a good start. And it follows the actual architecture
of the software, which is another good point.
The bad thing is that I couldn't see myself writing 32479083 lines of codes
only to retrieve an object, find a child, or whatsoever. Hence why I
started to monkey patch it.
As for your code snippet, the library doesn't differ from this exact
example atm. There's not hundred of ways of monkey patching after all.
Now, let's look into a different example, patching a class method:
class MyClass(object):
@classmethod
def whoAmI(cls):
print("My name is whatever")
print(whoAmI)
print(MyClass.whoAmI)
Both print statements won't print the same thing. The one nested within the
class will return the `classmethod` object while the other will return an
object resulting from the Python's descriptor protocol. So basically, you'd
have to write your `OpenMaya.MFnTransform.whoAmI = whoAmI` assignment
within the class if you want to preserve the class method descriptor in the
`OpenMaya.MFnTransform` class, or else you might get a result that you
didn't expect.
By using a decorator instead, you know what object you're using as a patch.
If you write the decorator on top of `@classmethod`, then the class method
gets patched. If you write it below it, then only the underlying function
gets patched. More intuitive and visual.
Furthermore, if you now want to patch 50 methods inside `
OpenMaya.MFnTransform` for example, then instead of writing 50 times this
assignment, you could write those 50 methods within a class and mark the
entire class to use as a patch. That's actually pretty much the only magic
happening in the library and I'll probably have to turn it into a setting
so we can disable this behavior if needed.
@gorilla.patch(OpenMaya, name='MFnTransform')
class MyClass(object):
def whoAmI(self):
print("My name is %s" % self.name())
Now that becomes a real advantage. Each method defined within `MyClass` get
individually inserted in the `OpenMaya.MFnTransform` class. If instead you
used something like `OpenMaya.MFnTransform = MyClass`, then you would have
completely overriden the original `OpenMaya.MFnTransform` class.
And finally, if a name clashing is detected, then the previous method is
backuped so you can still call it.
@gorilla.patch(OpenMaya)
class MFnTransform(object):
def transformation(self):
print("do something awesome")
return gorilla.get_original_attribute(self, 'transformation')()
Well, I've just been repeating the documentation really :)
But in short there's nothing happening in this library that you couldn't do
differently. Its goal is to make the process convenient and robust, without
you having to worry of eventual corner cases, and to ensure that this will
be portable across different versions of Python (Python 2.6+ and Python
3.3+ are currently supported).
I hope this answer your questions.
Cheers,
Christopher.
PS: funny that Gmail treats `self.name` as being an URL :)
On 23 June 2014 13:16, Marcus Ottosson <[email protected]> wrote:
> For someone who doesn’t generally monkey-patch things, what motivated you
> to make this library? Could you post a use-case? Looking at your example,
> how does your library differ from this?
>
> def whoAmI(self):
> print("My name is %s" % [self.name](http://self.name/)())
>
> OpenMaya.MFnTransform.whoAmI = whoAmI
>
> On another note, you’ve got a well executed readthedocs page and your
> docstrings are very well formatted. It’s quite a joy to read.
>
>
>
> On 23 June 2014 18:04, Marcus Ottosson <[email protected]> wrote:
>
>> Hey Christopher,
>>
>> I'm seeing the post fine on this end (via Gmail) and will look through
>> your code in a bit, looks cool!
>>
>> Best,
>> Marcus
>>
>>
>> On 23 June 2014 17:03, Christopher Crouzet <[email protected]
>> > wrote:
>>
>>> I think there has been a glitch with my Gmail—can anyone see a subject
>>> other than "untitled" or see this post at all?
>>>
>>>
>>>
>>> On 23 June 2014 11:47, Christopher Crouzet <
>>> [email protected]> wrote:
>>>
>>>> Hi there,
>>>>
>>>>
>>>> I've initially posted this message onto the Softimage mailing-list but
>>>> since it's referring to Maya I hope you don't mind me posting it here as
>>>> well.
>>>>
>>>> Basically I've just published an article about how to monkey patch
>>>> external libraries in Python while using the Maya Python API as a guinea
>>>> pig. While I was there, I also came up with a couple of open source
>>>> libraries on that matter.
>>>>
>>>> You can find the article and all the information over there: From
>>>> Monkey Patching the Maya Python API to Gorilla and Bananas
>>>> <http://christophercrouzet.com/blog/post/2014/06/23/From-Monkey-Patching-the-Maya-Python-API-to-Gorilla-and-Bananas>—I
>>>> hope you don't mind the bashing on the Maya API :)
>>>>
>>>>
>>>> And here's a short(er) version:
>>>>
>>>> Monkey patching allows you to modify an existing 3rd-party library by
>>>> inserting some code of yours. Once the process is done, you can call the
>>>> extensions you've inserted as if they have always been part of that
>>>> 3rd-party library.
>>>>
>>>> The article uses Maya as a playground but the technique can definitely
>>>> be applied to about anything, which is what the library Gorilla
>>>> <https://github.com/christophercrouzet/gorilla> is all about. You
>>>> write your functions, classes, methods, properties, whatever, you tell them
>>>> the target to patch with the help of a Python decorator, and that's about
>>>> it. You can find more details in the documentation
>>>> <http://gorilla.readthedocs.org/>.
>>>>
>>>> As a proof of concept for this project, I've developed a couple of
>>>> extensions for the Maya Python API. Say hi to Banana for Maya
>>>> <https://github.com/christophercrouzet/banana.maya>. This basically
>>>> shows that extending the API can be as simple as:
>>>>
>>>> @gorilla.patch(OpenMaya.MFnTransform)
>>>> def whoAmI(self):
>>>> print("My name is %s" % self.name())
>>>>
>>>>
>>>> Which allows you to fire the method through a call to `
>>>> OpenMaya.MFnTransform.whoAmI()`.
>>>>
>>>> As for the extensions already in there, there's a shiny documentation
>>>> <http://bananamaya.readthedocs.org/> for this one too.
>>>>
>>>> Once again the `banana.maya` package is only a proof of concept, which
>>>> is why it's a bit empty. I've started to implement some methods that could
>>>> hopefully be useful to everyone (mainly retrieving/iterating through the
>>>> nodes in the scene) but I'm currently not using Maya anymore and don't have
>>>> any direct interest in developing those extensions much further. The
>>>> exception being if there's a need for it and if discussions can be
>>>> organized to implement the right features.
>>>>
>>>> Note that I'm not saying that monkey patching the Maya Python API v1.0
>>>> is the way to go and I acknowledge that there's better alternatives out
>>>> there for most cases.
>>>>
>>>>
>>>> That's about it. The code is yours, do what you want with it.
>>>>
>>>> Cheers,
>>>> Christopher.
>>>>
>>>> --
>>>> Christopher Crouzet
>>>> *http://christophercrouzet.com* <http://christophercrouzet.com>
>>>>
>>>>
>>>
>>>
>>> --
>>> Christopher Crouzet
>>> *http://christophercrouzet.com* <http://christophercrouzet.com>
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Python Programming for Autodesk Maya" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/python_inside_maya/CANuKW52Luo-S-OabmBdxeXdfiCZuJTViV2MTju3pQyO8CXdLaQ%40mail.gmail.com
>>> <https://groups.google.com/d/msgid/python_inside_maya/CANuKW52Luo-S-OabmBdxeXdfiCZuJTViV2MTju3pQyO8CXdLaQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>>
>> --
>> *Marcus Ottosson*
>> [email protected]
>>
>
>
>
> --
> *Marcus Ottosson*
> [email protected]
>
> --
> You received this message because you are subscribed to the Google Groups
> "Python Programming for Autodesk Maya" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/python_inside_maya/CAFRtmOBkznpZeHg0pe09fzftXOuWg-JcwshZuUTdstGqdFA%3D8Q%40mail.gmail.com
> <https://groups.google.com/d/msgid/python_inside_maya/CAFRtmOBkznpZeHg0pe09fzftXOuWg-JcwshZuUTdstGqdFA%3D8Q%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>
> For more options, visit https://groups.google.com/d/optout.
>
--
Christopher Crouzet
*http://christophercrouzet.com* <http://christophercrouzet.com>
--
You received this message because you are subscribed to the Google Groups
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/python_inside_maya/CANuKW50Q-Jnyk2Hz0T1tUmD1b71ZWu%2BRoqaya8w6tEoX3i2zxw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.