Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
212 views
in Technique[技术] by (71.8m points)

python - Accessing the name that an object being created is assigned to

I'm writing some code to determine the name that an object is assigned to. This is for general debugging work and to further familiarize myself with python internals.

I have it structured as a class decorator so that all instances of that class will have their names recorded if it is possible to do. The code is fairly long so I won't post it unless asked. The general technique is as follows though

  1. decorate the class' __init__ method with the code to do what I want

  2. set caller = inspect.currentframe().f_back and open inspect.getframeinfo(caller).filename and send it to ast.parse. I don't do any error checking here because (1) this is just for debugging/profiling/hacking (2) this exact process was 'just' completed or the code wouldn't be running. Is there a problem with this?

  3. find the ast.Assignment instance that causes the currently executing __init__ method to run

  4. if len(assignment.targets) == 1 then there is only one item on the left hand side, and I can get the name out of targets[0].id. In a simple form like a = Foo(), then the assignment.value is an instance of ast.Call. if it's a literal (e.g. list), then value will be that list and bail because the object I'm interested in isn't being assigned to a name.

What is the best way to confirm that assignment.value.func is in fact type(obj).__call__ of the object that I'm interested in. I'm pretty sure that I'm guaranteed that It's "in there somewhere" or the code wouldn't even be running. I just need for it to be at the top level. The obvious thing to do is walk it and make sure that it doesn't contain any interior calls. Then I'm guaranteed that I have the name. (My reasoning is correct, I'm not sure if its assumptions are). This is not ideal though because if I'm interested in Foo, this could lead me to toss away a = Foo(Bar()) because I don't know if it's a = Bar(Foo()).

Of course I can just check assignment.value.func.id but then somebody could have done Foobar = Foo or something so I don't want to rely on this too heavily

Any help would be greatly appreciated. As always, I'm interested in any other suggestions or problems that I might be overlooking.

Also, I'm really surprised that I just had to invent the 'python-internals' tag.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The AST can't give you that answer. Try using frame.f_lasti and then peeking into the bytecode. If the next line isn't a STORE_FAST, you've got interior calls or something else going on other than the simple assignment you're looking for.

def f():
  f = sys._getframe()
  i = f.f_lasti + 3   # capture current point of execution, advance to expected store
  print dis.disco(f.f_code, i)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...