creating an object from base class

Steve Holden steve at holdenweb.com
Sat Apr 28 11:35:44 EDT 2007


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




More information about the Python-list mailing list