Getting not derived members of a class
Hello NG, I want to retrieve the members of a class with a baseclass. But the problem is, how to get the non derived members. class a: def who(self): print who def __init__(self): self._a = 3 class b(a): def who1(self): print who1 def __init__(self): a.__init__(self) self._b = 4 y=b() dir (y) ['__doc__', '__init__', '__module__', '_a', '_b', 'who', 'who1'] I need a function which lists only the members of the not derived class (here class B). _b _who1 __init__ How can I achieve this? With the introspect module or so? many thanks in advance! -- Franz Steinhaeusler -- http://mail.python.org/mailman/listinfo/python-list
Re: Getting not derived members of a class
Franz Steinhaeusler wrote: Hello NG, I want to retrieve the members of a class with a baseclass. But the problem is, how to get the non derived members. class a: def who(self): print who def __init__(self): self._a = 3 class b(a): def who1(self): print who1 def __init__(self): a.__init__(self) self._b = 4 y=b() dir (y) ['__doc__', '__init__', '__module__', '_a', '_b', 'who', 'who1'] I need a function which lists only the members of the not derived class (here class B). _b _who1 __init__ How can I achieve this? With the introspect module or so? I believe you can't: Both _a and _b end up in y.__dict__ and there's no way to differentiate between the two depending on the time of their creation. By the way, these are instance attributes, not class attributes, so strictly _b is not a member of B, it's just an instance of y. To see why this is the case, check the following valid (though highly discouraged) example: class X: def __init__(self, x): if isinstance(x,str): self._s = x else: self._n = x x1 = X(1) x2 = X(1) dir(x1) ['__doc__', '__init__', '__module__', '_s'] dir(x2) ['__doc__', '__init__', '__module__', '_n'] George -- http://mail.python.org/mailman/listinfo/python-list
Re: Getting not derived members of a class
On 1 Aug 2005 07:43:22 -0700, George Sakkis [EMAIL PROTECTED] wrote: Franz Steinhaeusler wrote: Hello NG, I want to retrieve the members of a class with a baseclass. But the problem is, how to get the non derived members. class a: def who(self): print who def __init__(self): self._a = 3 class b(a): def who1(self): print who1 def __init__(self): a.__init__(self) self._b = 4 y=b() dir (y) ['__doc__', '__init__', '__module__', '_a', '_b', 'who', 'who1'] I need a function which lists only the members of the not derived class (here class B). _b _who1 __init__ How can I achieve this? With the introspect module or so? I believe you can't: Both _a and _b end up in y.__dict__ and there's no way to differentiate between the two depending on the time of their creation. By the way, these are instance attributes, not class attributes, so strictly _b is not a member of B, it's just an instance of y. To see why this is the case, check the following valid (though highly discouraged) example: class X: def __init__(self, x): if isinstance(x,str): self._s = x else: self._n = x x1 = X(1) x2 = X(1) dir(x1) ['__doc__', '__init__', '__module__', '_s'] dir(x2) ['__doc__', '__init__', '__module__', '_n'] George Hello George, thank you for this information. This is a pity. The background: I want to create a code completition for an editor component. It should distinguish between inherited and non inherited members. Reason is, that on wxPython, most classes are derived from wxWindow. For example if I want Code completition for wx.Frame, I always get the 200 or so suggestions, whereby most times, I'm only interested in the possible completions of wx.Frame and maybe wx.TopLevelWindow. -- Franz Steinhaeusler -- http://mail.python.org/mailman/listinfo/python-list
Re: Getting not derived members of a class
On 'y', Python has no way of recording where '_a' and '_b' were set, so you can't tell whether it comes from class 'a' or 'b'. You can find the attributes that are defined on 'b' only, though, by using 'b.__dict__.keys()', or 'y.__class__.__dict__.__keys__()'. This gives ['__module__', 'who1', '__init__', '__doc__'] If you want to limit yourself to current versions of cpython (because the bytecode used in cpython is only an implementation detail) and define a 'member of class a' as one where a.__init__ has a statement like 'self.z = ...', you can peer into the bytecodes. Something like this: from dis import HAVE_ARGUMENT, opname LOAD_FAST = chr(opname.index('LOAD_FAST')) STORE_ATTR = chr(opname.index('STORE_ATTR')) HAVE_ARGUMENT = chr(HAVE_ARGUMENT) def find(cls): ns = cls.__dict__ result = ns.keys() init = ns.get('__init__', None) if not init: return ns f = ns['__init__'].func_code.co_code n = ns['__init__'].func_code.co_names i = 0 while i len(f) - 6: if (f[i] == LOAD_FAST and f[i+1] == f[i+2] == '\0' and f[i+3] == STORE_ATTR): j = ord(f[i+4]) + 256 * ord(f[i+5]) result.append(n[j]) i += 6 elif f[i] HAVE_ARGUMENT: i += 3 else: i += 1 return result import franz franz.find(y.__class__) ['__module__', 'who1', '__init__', '__doc__', '_b'] Jeff pgpU4zGsIJWPJ.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Getting not derived members of a class
Franz Steinhaeusler wrote: The background: I want to create a code completition for an editor component. It should distinguish between inherited and non inherited members. Reason is, that on wxPython, most classes are derived from wxWindow. For example if I want Code completition for wx.Frame, I always get the 200 or so suggestions, whereby most times, I'm only interested in the possible completions of wx.Frame and maybe wx.TopLevelWindow. You can, of course, always search the base classes and subtract the two sets (all members)-(members of baseclasses). For example: cls = wx.Frame set(dir(cls)) - reduce(set.union, [set(dir(base)) for base in cls.__bases__]) Reinhold -- http://mail.python.org/mailman/listinfo/python-list
Re: Getting not derived members of a class
On Mon, 1 Aug 2005 10:24:53 -0500, Jeff Epler [EMAIL PROTECTED] wrote: On 'y', Python has no way of recording where '_a' and '_b' were set, so you can't tell whether it comes from class 'a' or 'b'. You can find the attributes that are defined on 'b' only, though, by using 'b.__dict__.keys()', or 'y.__class__.__dict__.__keys__()'. This gives ['__module__', 'who1', '__init__', '__doc__'] If you want to limit yourself to current versions of cpython (because the bytecode used in cpython is only an implementation detail) and define a 'member of class a' as one where a.__init__ has a statement like 'self.z = ...', you can peer into the bytecodes. Something like this: from dis import HAVE_ARGUMENT, opname LOAD_FAST = chr(opname.index('LOAD_FAST')) STORE_ATTR = chr(opname.index('STORE_ATTR')) HAVE_ARGUMENT = chr(HAVE_ARGUMENT) def find(cls): ns = cls.__dict__ result = ns.keys() init = ns.get('__init__', None) if not init: return ns f = ns['__init__'].func_code.co_code n = ns['__init__'].func_code.co_names i = 0 while i len(f) - 6: if (f[i] == LOAD_FAST and f[i+1] == f[i+2] == '\0' and f[i+3] == STORE_ATTR): j = ord(f[i+4]) + 256 * ord(f[i+5]) result.append(n[j]) i += 6 elif f[i] HAVE_ARGUMENT: i += 3 else: i += 1 return result import franz franz.find(y.__class__) ['__module__', 'who1', '__init__', '__doc__', '_b'] Jeff Hello Jeff, thank you for this desciption. Well, a little complicated, I must read/try this later, but it looks promising to get the last derived class members ;) Is there any possibility to simply get out the classes and baseclasses of a class? somfunc (y) = class A, B (where B is last). Ok you can prepare a class, but I need to use the existing wxPython classes. -- Franz Steinhaeusler -- http://mail.python.org/mailman/listinfo/python-list
Re: Getting not derived members of a class
On Mon, 01 Aug 2005 18:02:20 +0200, Reinhold Birkenfeld [EMAIL PROTECTED] wrote: Franz Steinhaeusler wrote: The background: I want to create a code completition for an editor component. It should distinguish between inherited and non inherited members. Reason is, that on wxPython, most classes are derived from wxWindow. For example if I want Code completition for wx.Frame, I always get the 200 or so suggestions, whereby most times, I'm only interested in the possible completions of wx.Frame and maybe wx.TopLevelWindow. You can, of course, always search the base classes and subtract the two sets (all members)-(members of baseclasses). For example: cls = wx.Frame set(dir(cls)) - reduce(set.union, [set(dir(base)) for base in cls.__bases__]) Reinhold Hello Reinhold, yes, cool, thank you very much! The optimum would be getting also the other base classes, with the members, but I think, it is asked to much. 'wx.Frame' ... = CreateStatusBar, ... 'wx.TopLevelWindow' ... = GetIcon, ... 'wx.Window' ... = ... 'wx.EvtHandler' = ... -- Franz Steinhaeusler -- http://mail.python.org/mailman/listinfo/python-list
Re: Getting not derived members of a class
Franz Steinhaeusler wrote: Is there any possibility to simply get out the classes and baseclasses of a class? somfunc (y) = class A, B (where B is last). If you use new-style classes, i.e. classes inheriting from object, it is trivial: class X(object): pass class Y1(X): pass class Y2(X): pass class Z(Y1,Y2): pass z = Z() z.__class__.__mro__ (class '__main__.Z', class '__main__.Y1', class '__main__.Y2', class '__main__.X', type 'object') Old style classes don't have __mro__, so you have to write it yourself; in any case, writing old style classes in new code is discouraged. George -- http://mail.python.org/mailman/listinfo/python-list
Re: Getting not derived members of a class
George Sakkis wrote: z = Z() z.__class__.__mro__ (class '__main__.Z', class '__main__.Y1', class '__main__.Y2', class '__main__.X', type 'object') Old style classes don't have __mro__, so you have to write it yourself; in any case, writing old style classes in new code is discouraged. Notice also that George's __mro__ solution returns the bases in reverse order than what you requested (in your example, you said B should come last). So use list(reversed(z.__class__.__mro__)) or z.__class__.__mro__[::-1] -- Brian Beck Adventurer of the First Order -- http://mail.python.org/mailman/listinfo/python-list