Hi, subclassing CLR types does work as long as you hold a reference to the instance of the subclass in Python. But when you pass a subclassed object to a CLR object and retrieve this object later through a method of the CLR object you don't get an instance of the subclass but an instance of the CLR base class the subclass was derived from: Python 2.3.2 (#49, Oct 2 2003, 20:02:00) [MSC v.1200 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.
import CLR from CLR.System.Windows.Forms import Control c=Control("This is a Control.") class myControl(Control): ... def dummy(self): ... return self.Text ... m=myControl(c, "This is a myControl.") m.Parent
m.Parent.Text u'This is a Control.' c.Contains(m) True m.dummy() u'This is a myControl.' c.Controls[0] == m True
[Every thing ok, so far, but ...]
c.Controls[0].dummy() Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: 'Control' object has no attribute 'dummy'
[Because ...]
type(c.Controls[0])
This is weird because it means that when I get back an instance of a subclass from some CLR method I don't know the correct type and can not act on it properly. I don't know if there's an easy way to come around this problem but to me subclassing of CLR types seemes pretty useless without a solution for it. If there is some kind of unique reference from the Python wrapper instances to the CLR instances a starting point for a solution may be to base all wrappers on a base type which keeps a mapping of referenced CLR instances to wrapper instances. Something like this (all not tested yet!!!): class CLRObj(object): from weakref import WeakValueDictionary __objMap = WeakValueDictionary() def __new__(cls, ref): try: obj = clrObj.__objMap[ref] except KeyError: obj = object.__new__(cls) obj._ref = ref clrObj.__objMap[ref] = obj return obj def __del__(self): self._ref.Dispose() class <wrapper>(CLRObj): def __new__(cls, ...): ref = <create base CLR type> return CLRObj.__new__(cls, ref) ... and when receiving a CLR instance turn it into the corresponding wrapper instance by obj = CLRObj(clrObj) This will not work if you receive some kind of CLR object which was created internally by some CLR method and not through a wrapper. But you will get all object you created through the wrappers back as instances of the correct type. If I'm galloping in the wrong direction please give me a short stop signal. If not ... lets figure out the probably missing details. Michael
participants (2)
-
Brian Lloyd
-
Michael.Amrhein@t-online.de