Getting not derived members of a class

2005-08-01 Thread Franz Steinhaeusler
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

2005-08-01 Thread George Sakkis
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

2005-08-01 Thread Franz Steinhaeusler
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

2005-08-01 Thread Jeff Epler
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

2005-08-01 Thread Reinhold Birkenfeld
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

2005-08-01 Thread Franz Steinhaeusler
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

2005-08-01 Thread Franz Steinhaeusler
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

2005-08-01 Thread George Sakkis
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

2005-08-01 Thread Brian Beck
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