On Mon, 21 Apr 2014 09:06:14 -0500, Skip Montanaro wrote: [...] > Now, dir(inst_b) will list both 'x' and 'y' as attributes (along with > the various under under attributes). Without examining the source, is it > possible to define some kind of "selective" dir, with a API like > > def selective_dir(inst, class_): pass > > which will list only those attributes of inst which were first defined > in (some method defined by) class_? The output of calls with different > class_ args would yield different lists: > > selective_dir(inst_b, B) -> ['y'] > > selective_dir(inst_b, A) -> ['x']
In general, no. There's no way of telling what method added an attribute after the event has taken place: given that instance.__dict__ has a key "x", how do you know how it got there? You may be able to do this cooperatively: have both A and B define a __dir__ method which lists only the attributes they contribute, then call dir(A) or dir(B) as necessary. Or, if you find yourself in the position of having an instance of both A and B, say, a and b, you can compare dir(a) and dir(b). Anything in the later but not in the former probably was added by B not A. I say "probably" because one might have things like this: class A: def __init__(self): if type(self) is not A: self.y = "Surprise!" self.x = "something" and of course don't forget that attributes can be added by external entities too: instance = A() instance.z = "bet you forgot about this" > I'm thinking some sort of gymnastics with inspect might do the trick, > but after a quick skim of that module's functions nothing leapt out at > me. OTOH, working through the code objects for the methods looks > potentially promising: > >>>> B.__init__.im_func.func_code.co_names > ('A', '__init__', 'y') >>>> A.__init__.im_func.func_code.co_names > ('x',) You may have a bit of difficulty with classes that write directly to the __dict__, or use setattr, or eval. -- Steven D'Aprano http://import-that.dreamwidth.org/ -- https://mail.python.org/mailman/listinfo/python-list