Getting not derived members of a class
Franz Steinhaeusler
franz.steinhaeusler at gmx.at
Mon Aug 1 12:00:42 EDT 2005
On Mon, 1 Aug 2005 10:24:53 -0500, Jeff Epler <jepler at unpythonic.net>
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
More information about the Python-list
mailing list