creating an object from base class

Discussion in 'Python' started by iogilvy@attglobal.net, Apr 27, 2007.

  1. Guest

    i wish to have some extended functionality added to sockets

    i can create my own socket class class mysocket(socket.socket):

    and all should be fine. Except, the sockets are created for me by the
    accept method, listening on port. So how can i take the standard
    socket created for me and create a 'mysocket'. I need a method that
    will initialise any new properties i have added in my class, but how
    can i change the class of the socket created?
     
    , Apr 27, 2007
    #1
    1. Advertising

  2. Ian Clark Guest

    Quote iogilvy:
    > i wish to have some extended functionality added to sockets
    >
    > i can create my own socket class class mysocket(socket.socket):
    >
    > and all should be fine. Except, the sockets are created for me by the
    > accept method, listening on port. So how can i take the standard
    > socket created for me and create a 'mysocket'. I need a method that
    > will initialise any new properties i have added in my class, but how
    > can i change the class of the socket created?
    >


    Someone correct me if I'm wrong, but I don't believe it's possible to
    change the type of objects made from builtin classes. Though if it's a
    custom class you can, for example:

    >>> class Foo: pass
    >>> class Bar: pass
    >>> obj = Foo()
    >>> obj.__class__ = Bar



    One option is to make your custom socket a wrapper around
    socket.socket and then pass through the calls you don't want to handle
    to socket.socket. The downside to this is there are quite a lot of
    methods that need to be accounted for. For example:

    >>> class CustomSocket:
    >>> def __init__(self, socket):
    >>> self.socket = socket
    >>> def connect(self, address):
    >>> self.socket.connect( address + '.some.tld' )
    >>> [etc]
    >>>
    >>> ...
    >>>
    >>> s = server_socket.accept()
    >>> s = CustomSocket(s)



    Another approach you might want to look at is populating your object
    at runtime through a function. This won't give it the type you want,
    but it will give it any methods and attributes it would have gotten
    from your class with the added benefit of it still being of type
    socket.socket. Example:

    >>> def modify_socket( socket ):
    >>> socket.cabbages = 'Yuk'
    >>> socket.apples = 'Yum'
    >>>
    >>> def info():
    >>> print 'Cabbages? %s\nApples? %s' % (socket.cabbages, socket.apples)
    >>> obj.show_info = info
    >>>
    >>> ...
    >>>
    >>> s = server_socket.accept()
    >>> modify_socket( s )
    >>> s.show_info()

    Cabbages? Yuk
    Apples? Yum
    >>> s.apples = 'Yummie'
    >>> s.show_info()

    Cabbages? Yuk
    Apples? Yummie
    >>> type(s)

    <class 'socket._socketobject'>

    Good luck.

    Ian
     
    Ian Clark, Apr 27, 2007
    #2
    1. Advertising

  3. a écrit :
    > i wish to have some extended functionality added to sockets
    >
    > i can create my own socket class class mysocket(socket.socket):
    >
    > and all should be fine. Except, the sockets are created for me by the
    > accept method, listening on port. So how can i take the standard
    > socket created for me and create a 'mysocket'. I need a method that
    > will initialise any new properties i have added in my class, but how
    > can i change the class of the socket created?


    object.__class__ = OtherClass

    But this may not be the wisest solution. What you want is not
    inheritance, it's decoration (AKA wrapping). IOW : instead of directly
    using accept(), use a wrapper around it that will returns socket objects
    wrapped in your own class.

    My 2 cents...
     
    Bruno Desthuilliers, Apr 27, 2007
    #3
  4. Steve Holden Guest

    Ian Clark wrote:
    > Quote iogilvy:
    >> i wish to have some extended functionality added to sockets
    >>
    >> i can create my own socket class class mysocket(socket.socket):
    >>
    >> and all should be fine. Except, the sockets are created for me by the
    >> accept method, listening on port. So how can i take the standard
    >> socket created for me and create a 'mysocket'. I need a method that
    >> will initialise any new properties i have added in my class, but how
    >> can i change the class of the socket created?
    >>

    >
    > Someone correct me if I'm wrong, but I don't believe it's possible to
    > change the type of objects made from builtin classes. Though if it's a
    > custom class you can, for example:
    >
    >>>> class Foo: pass
    >>>> class Bar: pass
    >>>> obj = Foo()
    >>>> obj.__class__ = Bar

    >
    >

    Yes, assuming you weren't asking a rhetorical question you will
    eventually run up against

    >>> class myClass1(object): pass

    ...
    >>> class myClass2(object): pass

    ...
    >>> mc1 = myClass1()
    >>> type(mc1)

    <class '__main__.myClass1'>
    >>> mc1.__class__ = myClass2
    >>> type(mc1)

    <class '__main__.myClass2'>
    >>> 2 . __class__ = myClass1

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: __class__ assignment: only for heap types
    >>>


    This doesn't qualify as error message of the year, but it clearly tells
    you you aren't going to get around the prohibition. We also see

    >>> o = object
    >>> o.__class__ = myClass2

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: can't set attributes of built-in/extension type 'object'
    >>>


    which gives a much better error message. Of course it'll probably only
    take Alex Martelli a few minutes to find a workaround or counter-example.

    > One option is to make your custom socket a wrapper around
    > socket.socket and then pass through the calls you don't want to handle
    > to socket.socket. The downside to this is there are quite a lot of
    > methods that need to be accounted for. For example:
    >
    >>>> class CustomSocket:
    >>>> def __init__(self, socket):
    >>>> self.socket = socket
    >>>> def connect(self, address):
    >>>> self.socket.connect( address + '.some.tld' )
    >>>> [etc]
    >>>>
    >>>> ...
    >>>>
    >>>> s = server_socket.accept()
    >>>> s = CustomSocket(s)

    >

    This technique is formally called "delegation" if you want to Google it.
    >
    > Another approach you might want to look at is populating your object
    > at runtime through a function. This won't give it the type you want,
    > but it will give it any methods and attributes it would have gotten
    > from your class with the added benefit of it still being of type
    > socket.socket. Example:
    >
    >>>> def modify_socket( socket ):
    >>>> socket.cabbages = 'Yuk'
    >>>> socket.apples = 'Yum'
    >>>>
    >>>> def info():
    >>>> print 'Cabbages? %s\nApples? %s' % (socket.cabbages, socket.apples)
    >>>> obj.show_info = info
    >>>>
    >>>> ...
    >>>>
    >>>> s = server_socket.accept()
    >>>> modify_socket( s )
    >>>> s.show_info()

    > Cabbages? Yuk
    > Apples? Yum
    >>>> s.apples = 'Yummie'
    >>>> s.show_info()

    > Cabbages? Yuk
    > Apples? Yummie
    >>>> type(s)

    > <class 'socket._socketobject'>
    >

    Of course that approach sucks if sockets happen to have an organes or
    apples attribute that's used in the inner workings of the class. This is
    when the C++ devotees start screaming about protected and private
    variables. Just ignore them :)

    [Note: these remarks are more for the OP than Ian]

    regards
    Steve
    --
    Steve Holden +1 571 484 6266 +1 800 494 3119
    Holden Web LLC/Ltd http://www.holdenweb.com
    Skype: holdenweb http://del.icio.us/steve.holden
    ------------------ Asciimercial ---------------------
    Get Python in your .sig and on the web. Blog and lens
    holdenweb.blogspot.com squidoo.com/pythonology
    tag items: del.icio.us/steve.holden/python
    All these services currently offer free registration!
    -------------- Thank You for Reading ----------------
     
    Steve Holden, Apr 28, 2007
    #4
    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. Replies:
    9
    Views:
    573
    justanotherguy
    Dec 3, 2004
  2. Alf P. Steinbach
    Replies:
    6
    Views:
    549
    John Carson
    Sep 3, 2005
  3. DanielJohnson
    Replies:
    7
    Views:
    2,011
    James Kanze
    Jan 17, 2009
  4. Hicham Mouline
    Replies:
    1
    Views:
    596
    Victor Bazarov
    Apr 20, 2009
  5. Karan Rajput
    Replies:
    2
    Views:
    145
    Abinoam Jr.
    Dec 22, 2010
Loading...

Share This Page