Re: Partial 1.0 - Partial classes for Python

Discussion in 'Python' started by Thomas Heller, Feb 7, 2007.

  1. Martin v. Löwis schrieb:
    > I'm happy to announce partial 1.0; a module to implement
    > partial classes in Python. It is available from
    >
    > http://cheeseshop.python.org/pypi/partial/1.0
    >
    > A partial class is a fragment of a class definition;
    > partial classes allow to spread the definition of
    > a class over several modules. One location serves
    > as the original definition of the class.
    >
    > To extend a class original_module.FullClass with
    > an additional function, one writes
    >
    > from partial import *
    > import original_module
    >
    > class ExtendedClass(partial, original_module.FullClass):
    > def additional_method(self, args):
    > body
    > more_methods
    >
    > This module is licensed under the Academic Free License v3.0.
    >
    > Please send comments and feedback to


    Nice idea. I had to apply this change to make it work, though:

    diff -u c:\python25\lib\site-packages\partial-1.0-py2.5.egg\partial.py.orig c:\python25\lib\site-packages\partial-1.0-py2.5.egg\partial.py
    --- c:\python25\lib\site-packages\partial-1.0-py2.5.egg\partial.py.orig Wed Feb 07 13:47:55 2007
    +++ c:\python25\lib\site-packages\partial-1.0-py2.5.egg\partial.py Wed Feb 07 13:47:55 2007
    @@ -36,7 +36,7 @@
    continue
    if k in base.__dict__ and not hasattr(v, '__replace'):
    raise TypeError, "%s already has %s" % (repr(base), k)
    - base.__dict__[k] = v
    + setattr(base, k, v)
    # Return the original class
    return base

    otherwise I get this:

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "c:\python25\lib\site-packages\partial-1.0-py2.5.egg\partial.py", line 39, in __new__
    base.__dict__[k] = v
    TypeError: Error when calling the metaclass bases
    'dictproxy' object does not support item assignment


    IIUC, wouldn't be 'partial.extend' or something like that be a better name
    for the base class?

    Thanks,
    Thomas
     
    Thomas Heller, Feb 7, 2007
    #1
    1. Advertising

  2. Thomas Heller

    Carl Banks Guest

    On Feb 7, 8:51 am, Thomas Heller <> wrote:
    > Martin v. Löwis schrieb:
    >
    > > I'm happy to announce partial 1.0; a module to implement
    > > partial classes in Python. It is available from

    >
    > >http://cheeseshop.python.org/pypi/partial/1.0

    >
    > > A partial class is a fragment of a class definition;
    > > partial classes allow to spread the definition of
    > > a class over several modules. One location serves
    > > as the original definition of the class.

    >
    > > To extend a class original_module.FullClass with
    > > an additional function, one writes

    >
    > > from partial import *
    > > import original_module

    >
    > > class ExtendedClass(partial, original_module.FullClass):
    > > def additional_method(self, args):
    > > body
    > > more_methods

    >
    > > This module is licensed under the Academic Free License v3.0.

    >
    > > Please send comments and feedback to

    >
    > Nice idea.


    Indeed. I was going to make a post asking for advice on high-level
    delegation (basically you have a generic mostly-OO framework, which
    the user extends mostly by subclassing, but how do the generic classes
    know about the user-extened classes?). I knew of many solutions, but
    all had significant drawbacks. But this seems like it'd work great,
    maybe with a few minor inconveniences but nothing like the icky hacks
    I've been using.

    Ironic, since I myself posted a very simple example of how to do this
    with a class hook here on c.l.python a while back.

    But I'll have to review the license and see how it works with what I
    have.


    Carl Banks
     
    Carl Banks, Feb 7, 2007
    #2
    1. Advertising

  3. Thomas Heller

    Carl Banks Guest

    On Feb 7, 10:17 am, "Carl Banks" <> wrote:
    > On Feb 7, 8:51 am, Thomas Heller <> wrote:
    >
    >
    >
    > > Martin v. Löwis schrieb:

    >
    > > > I'm happy to announce partial 1.0; a module to implement
    > > > partial classes in Python. It is available from

    >
    > > >http://cheeseshop.python.org/pypi/partial/1.0

    >
    > > > A partial class is a fragment of a class definition;
    > > > partial classes allow to spread the definition of
    > > > a class over several modules. One location serves
    > > > as the original definition of the class.

    >
    > > > To extend a class original_module.FullClass with
    > > > an additional function, one writes

    >
    > > > from partial import *
    > > > import original_module

    >
    > > > class ExtendedClass(partial, original_module.FullClass):
    > > > def additional_method(self, args):
    > > > body
    > > > more_methods

    >
    > > > This module is licensed under the Academic Free License v3.0.

    >
    > > > Please send comments and feedback to

    >
    > > Nice idea.

    >
    > Indeed. I was going to make a post asking for advice on high-level
    > delegation (basically you have a generic mostly-OO framework, which
    > the user extends mostly by subclassing, but how do the generic classes
    > know about the user-extened classes?). I knew of many solutions, but
    > all had significant drawbacks. But this seems like it'd work great,
    > maybe with a few minor inconveniences but nothing like the icky hacks
    > I've been using.
    >
    > Ironic, since I myself posted a very simple example of how to do this
    > with a class hook here on c.l.python a while back.


    And looking back at that post, I said that using such a hack would be
    "truly evil". To every thing there is a season....


    Carl Banks
     
    Carl Banks, Feb 7, 2007
    #3
  4. > Martin v. Löwis schrieb:
    >
    >
    >
    > > I'm happy to announce partial 1.0; a module to implement
    > > partial classes in Python. It is available from

    >
    > >http://cheeseshop.python.org/pypi/partial/1.0

    >
    > > A partial class is a fragment of a class definition;
    > > partial classes allow to spread the definition of
    > > a class over several modules. One location serves
    > > as the original definition of the class.


    This looks the same as Ruby classes, right?
    I don't like class definitions to be scattered in different files, for
    the same reason
    I don't like excessive inheritance, it is too easy to get lost when
    debugging
    code written by somebody else. But probably I am just overreacting due
    to my
    exposure to Zope ...

    Michele Simionato
     
    Michele Simionato, Feb 7, 2007
    #4
  5. Thomas Heller

    Carl Banks Guest

    On Feb 7, 10:48 am, "Michele Simionato" <>
    wrote:
    > > Martin v. Löwis schrieb:

    >
    > > > I'm happy to announce partial 1.0; a module to implement
    > > > partial classes in Python. It is available from

    >
    > > >http://cheeseshop.python.org/pypi/partial/1.0

    >
    > > > A partial class is a fragment of a class definition;
    > > > partial classes allow to spread the definition of
    > > > a class over several modules. One location serves
    > > > as the original definition of the class.

    >
    > This looks the same as Ruby classes, right?
    > I don't like class definitions to be scattered in different files, for
    > the same reason
    > I don't like excessive inheritance, it is too easy to get lost when
    > debugging
    > code written by somebody else. But probably I am just overreacting due
    > to my
    > exposure to Zope ...


    The big difference from Ruby is that this can't extend most built-
    ins. Which means that a lot of Ruby horror stories wouldn't apply.


    Carl Banks
     
    Carl Banks, Feb 7, 2007
    #5
  6. Carl Banks schrieb:
    > On Feb 7, 10:17 am, "Carl Banks" <> wrote:
    >> On Feb 7, 8:51 am, Thomas Heller <> wrote:
    >>
    >>
    >>
    >> > Martin v. Löwis schrieb:

    >>
    >> > > I'm happy to announce partial 1.0; a module to implement
    >> > > partial classes in Python. It is available from

    >>
    >> > >http://cheeseshop.python.org/pypi/partial/1.0

    >>
    >> > > A partial class is a fragment of a class definition;
    >> > > partial classes allow to spread the definition of
    >> > > a class over several modules. One location serves
    >> > > as the original definition of the class.

    >>
    >> > > To extend a class original_module.FullClass with
    >> > > an additional function, one writes

    >>
    >> > > from partial import *
    >> > > import original_module

    >>
    >> > > class ExtendedClass(partial, original_module.FullClass):
    >> > > def additional_method(self, args):
    >> > > body
    >> > > more_methods

    >>
    >> > > This module is licensed under the Academic Free License v3.0.

    >>
    >> > > Please send comments and feedback to

    >>
    >> > Nice idea.

    >>
    >> Indeed. I was going to make a post asking for advice on high-level
    >> delegation (basically you have a generic mostly-OO framework, which
    >> the user extends mostly by subclassing, but how do the generic classes
    >> know about the user-extened classes?). I knew of many solutions, but
    >> all had significant drawbacks. But this seems like it'd work great,
    >> maybe with a few minor inconveniences but nothing like the icky hacks
    >> I've been using.
    >>
    >> Ironic, since I myself posted a very simple example of how to do this
    >> with a class hook here on c.l.python a while back.

    >
    > And looking back at that post, I said that using such a hack would be
    > "truly evil". To every thing there is a season....


    Do you have a pointer to that post?

    Thomas
     
    Thomas Heller, Feb 7, 2007
    #6
  7. Thomas Heller wrote:
    >
    > Do you have a pointer to that post?
    >


    I think that he was refering to this post:
    http://mail.python.org/pipermail/python-list/2006-December/416241.html

    If you are interested in various implementations there is also this:
    http://mail.python.org/pipermail/python-list/2006-August/396835.html

    and a module from PyPy:
    http://mail.python.org/pipermail/python-dev/2006-July/067501.html

    which was moved to a new location:
    https://codespeak.net/viewvc/pypy/dist/pypy/tool/pairtype.py?view=markup

    Ziga
     
    Ziga Seilnacht, Feb 7, 2007
    #7
  8. Thomas Heller

    greg Guest

    > Martin v. Löwis schrieb:
    >
    >>A partial class is a fragment of a class definition;
    >>partial classes allow to spread the definition of
    >>a class over several modules.


    When I want to do this, usually I define the parts
    as ordinary, separate classes, and then define the
    main class as inheriting from all of them. That
    avoids the monkeypatching-like behaviour of what
    you're doing -- the main class definition makes it
    clear what parts it's made up of -- and it uses
    only standard Python techniques, so it doesn't
    harbour any surprises.

    --
    Greg
     
    greg, Feb 8, 2007
    #8
  9. Thomas Heller

    Guest

    greg> When I want to do this, usually I define the parts as ordinary,
    greg> separate classes, and then define the main class as inheriting
    greg> from all of them.

    Agreed. Maybe it's just my feeble brain, but I find this the most
    compelling (and easy to understand) use for multiple inheritance by far.

    Skip
     
    , Feb 8, 2007
    #9
  10. On Feb 8, 1:04 pm, wrote:
    > greg> When I want to do this, usually I define the parts as ordinary,
    > greg> separate classes, and then define the main class as inheriting
    > greg> from all of them.
    >
    > Agreed. Maybe it's just my feeble brain, but I find this the most
    > compelling (and easy to understand) use for multiple inheritance by far.
    >
    > Skip


    That is a common design, but I don't like it, since it becomes very
    easy to get
    classes with dozens of methods inherited from everywhere, a modern
    incarnation
    of the spaghetti-code concept. I find it much better to use
    composition, i.e. to
    encapsulate the various behaviors in different objects and to add them
    as
    attributes. In other words, instead of a flat class namespace with
    hundreds
    of methods, I prefer a hierarchical namespace, a class with few
    attributes, which
    in turns have their own attributes, and so on. In other words, nested
    is better
    than flatten ;)


    Michele Simionato

    P.S. Of course I mean situations where the methods can be meaningfully
    grouped
    together, which I find is the most common case.
     
    Michele Simionato, Feb 8, 2007
    #10
  11. Thomas Heller

    Guest

    Michele> That is a common design, but I don't like it, since it becomes
    Michele> very easy to get classes with dozens of methods inherited from
    Michele> everywhere, a modern incarnation of the spaghetti-code
    Michele> concept. I find it much better to use composition, i.e. to
    Michele> encapsulate the various behaviors in different objects and to
    Michele> add them as attributes.

    Composition is great when you know how largish classes are going to be
    composed ahead of time and/or already have the pieces available in the form
    of other classes you want to reuse. I use this fragment-by-multiple-
    inheritance (I hesitate to call it a) pattern when I realize after a long
    period of organic growth that a single-inheritance class has gotten too big.
    It's often relatively easy to carve the class up into multiple related base
    classes. The next step after that might be to morph those independent base
    classes back into delegated attributes.

    Skip
     
    , Feb 8, 2007
    #11
  12. On Feb 8, 4:05 pm, wrote:>
    > Composition is great when you know how largish classes are going to be
    > composed ahead of time and/or already have the pieces available in the form
    > of other classes you want to reuse. I use this fragment-by-multiple-
    > inheritance (I hesitate to call it a) pattern when I realize after a long
    > period of organic growth that a single-inheritance class has gotten too big.
    > It's often relatively easy to carve the class up into multiple related base
    > classes. The next step after that might be to morph those independent base
    > classes back into delegated attributes.
    >
    > Skip


    I know, I just try to avoid the multiple inheritance transitional
    state and switch directly
    to the last step ;)

    M. Simionato
     
    Michele Simionato, Feb 8, 2007
    #12
  13. Ziga Seilnacht schrieb:
    > Thomas Heller wrote:
    >>
    >> Do you have a pointer to that post?
    >>

    >
    > I think that he was refering to this post:
    > http://mail.python.org/pipermail/python-list/2006-December/416241.html
    >
    > If you are interested in various implementations there is also this:
    > http://mail.python.org/pipermail/python-list/2006-August/396835.html
    >
    > and a module from PyPy:
    > http://mail.python.org/pipermail/python-dev/2006-July/067501.html
    >
    > which was moved to a new location:
    > https://codespeak.net/viewvc/pypy/dist/pypy/tool/pairtype.py?view=markup
    >


    Thanks for these links. It seems they all (including Martin's partial) implementation
    all use more or less the same trick (or hack ;-).

    I agree with most of the posters is this thread that it is confusing to spread
    the definition of a class over several places or files.

    But, there are cases where the trick come in handy - when classes are created
    not by class statements.

    In ctypes, for example, a pointer type to a ctypes type is created by calling
    the POINTER function which creates a new class. When you have done this, the
    usual way to add additional methods to the new class is by assigning them like this:

    from ctypes import *

    pointer_to_c_int = POINTER(c_int)

    @classmethod
    def from_param(cls, value):
    ... do something ...

    pointer_to_c_int.from_param = from_param

    IMO, using the tricky class in the recipes mentioned above, you can write instead:

    class pointer_to_c_int(partial, POINTER(c_int)):
    @classmethod
    def from_param(cls, value):
    ... do something ...

    Thomas
     
    Thomas Heller, Feb 8, 2007
    #13
  14. On Feb 8, 8:15 pm, Thomas Heller <> wrote:
    > I agree with most of the posters is this thread that it is confusing to spread
    > the definition of a class over several places or files.
    >
    > But, there are cases where the trick come in handy - when classes are created
    > not by class statements.
    >
    > In ctypes, for example, a pointer type to a ctypes type is created by calling
    > the POINTER function which creates a new class. When you have done this, the
    > usual way to add additional methods to the new class is by assigning them like this:
    >
    > from ctypes import *
    >
    > pointer_to_c_int = POINTER(c_int)
    >
    > @classmethod
    > def from_param(cls, value):
    > ... do something ...
    >
    > pointer_to_c_int.from_param = from_param
    >
    > IMO, using the tricky class in the recipes mentioned above, you can write instead:
    >
    > class pointer_to_c_int(partial, POINTER(c_int)):
    > @classmethod
    > def from_param(cls, value):
    > ... do something ...
    >
    > Thomas


    Using a simple decorator like this seeems a better option to me:

    def attach_to(cls):
    def attach_method(meth):
    setattr(cls, meth.__name__, meth)
    return meth
    return attach_meth

    @attach_to(pointer_to_c)
    @classmethod
    def from_param(cls, value):
    ... do something ...


    Michele Simionato
     
    Michele Simionato, Feb 8, 2007
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?VmFkaW0=?=

    Is there a way to sign partial classes in Whidbey?

    =?Utf-8?B?VmFkaW0=?=, Jan 12, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    601
    Juan T. Llibre
    Jan 13, 2005
  2. C.Batt
    Replies:
    6
    Views:
    2,023
    Brock Allen
    May 2, 2005
  3. =?Utf-8?B?UGF0cmljaw==?=

    ASP.Net 2.0 and partial classes

    =?Utf-8?B?UGF0cmljaw==?=, Apr 25, 2005, in forum: ASP .Net
    Replies:
    7
    Views:
    2,733
    clintonG
    Apr 26, 2005
  4. Billy
    Replies:
    2
    Views:
    524
    Billy
    Feb 1, 2006
  5. J. Clifford Dyer

    Re: Partial 1.0 - Partial classes for Python

    J. Clifford Dyer, Feb 8, 2007, in forum: Python
    Replies:
    0
    Views:
    536
    J. Clifford Dyer
    Feb 8, 2007
Loading...

Share This Page