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 ---------------- -- http://mail.python.org/mailman/listinfo/python-list