Re: addition of "nameof" operator
Here's a simple runtime implementation that doesn't require any dependencies or source code access: import dis import inspect from functools import lru_cache def nameof(_): frame = inspect.currentframe().f_back return _nameof(frame.f_code, frame.f_lasti) @lru_cache def _nameof(code, offset): instructions = list(dis.get_instructions(code)) (current_instruction_index, current_instruction), = ( (index, instruction) for index, instruction in enumerate(instructions) if instruction.offset == offset ) assert current_instruction.opname == "CALL_FUNCTION" name_instruction = instructions[current_instruction_index - 1] assert name_instruction.opname.startswith("LOAD_") return name_instruction.argrepr def test(): print(nameof(dis)) print(nameof(dis.get_instructions)) x = 1 print(nameof(x)) if __name__ == '__main__': test()
On Sat, Feb 01, 2020 at 01:52:38AM +0200, Alex Hall wrote:
Here's a simple runtime implementation that doesn't require any dependencies or source code access:
import dis
So this is not likely to ever work in IronPython or Jython. There are no stability guarantees about the byte-code generated by CPython, so you may be chasing a moving target here. You ought to test your code before posting, because I've tried it in 3.5, 3.7 and 3.8 and I get the same error each time: TypeError: Expected maxsize to be an integer or None which is a simple error in the call to the lru_cache decorator. After fixing that, I tried it again in 3.7 and I get this: >>> x = 1 >>> nameof.nameof(x) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/srv-steve/python/nameof.py", line 7, in nameof return _nameof(frame.f_code, frame.f_lasti) File "/home/srv-steve/python/nameof.py", line 17, in _nameof assert current_instruction.opname == "CALL_FUNCTION" AssertionError -- Steven
I am really confused by this whole thread: (I know this has all been said in this thread, but I’m summarizing to get us on the same page for the following comments) Python has names, and it has values (objects, whatever) when we write Python, we bind names to values with the = operator. (And other namespace trickery). Some types of objects do have a __name__ attribute: classes, functions created with def. But that name is only sometimes the same as the name(s) it might be bound to in any given namespace. So what the heck is nameof() supposed to mean? A few examples:
x = 5 nameof(x)
OK, I suppose that’s “x” — but what is the point of that? You have to know the name already. What about: y = 5 x = 5 (Or x = y) What is nameof(x) And nameof(y)? What about nameof(5)? Now: def fun(): pass I suppose nameof(fun) is “fun”, but again, is that useful? And now: Fred = fun What’s nameof(Fred) If it’s “Fred” then again, useless. If it’s “fun” then what about x and y before? And: def fun(): y = something return y lst.append(fun()) nameof(lst[-1]) ???? In short, if it means “what is the name of this name” that seems completely useless? If it means: what name is this object bound to in this namespace? Than I can see how one might think that would be useful, but the answer could be: No name at all More than one name A name different than the object’s __name__ And then there is the question of the local vs global namespace, the list goes on. This thread has been going on a while: What am I missing? -CHB
-- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
On 1/31/20 9:28 PM, Christopher Barker wrote:
I am really confused by this whole thread:
(I know this has all been said in this thread, but I’m summarizing to get us on the same page for the following comments)
Python has names, and it has values (objects, whatever) when we write Python, we bind names to values with the = operator. (And other namespace trickery). Some types of objects do have a __name__ attribute: classes, functions created with def.
But that name is only sometimes the same as the name(s) it might be bound to in any given namespace. So what the heck is nameof() supposed to mean? A few examples:
x = 5 nameof(x)
OK, I suppose that’s “x” — but what is the point of that? You have to know the name already.
What about:
y = 5 x = 5 (Or x = y)
What is nameof(x) And nameof(y)?
What about nameof(5)?
Now:
def fun(): pass
I suppose nameof(fun) is “fun”, but again, is that useful?
And now:
Fred = fun
What’s nameof(Fred)
If it’s “Fred” then again, useless.
If it’s “fun” then what about x and y before?
And:
def fun(): y = something return y
lst.append(fun())
nameof(lst[-1])
????
In short, if it means “what is the name of this name” that seems completely useless?
If it means: what name is this object bound to in this namespace? Than I can see how one might think that would be useful, but the answer could be:
No name at all More than one name A name different than the object’s __name__
And then there is the question of the local vs global namespace, the list goes on.
This thread has been going on a while:
What am I missing?
-CHB
My understanding is that the impetus of the request is that if you start from an expression like nameof(foo.bar) to get to "bar" then if you refactor your code you have a chance that the tool will be able to see the variable expression foo.bar, and process that like other references to the item, and thus be able to change it. Just using the string "bar" would be very hard to see the connection between foo.bar and "bar". -- Richard Damon
On Fri, Jan 31, 2020 at 9:50 PM Richard Damon <Richard@damon-family.org> wrote:
On 1/31/20 9:28 PM, Christopher Barker wrote:
I am really confused by this whole thread:
<snio>
My understanding is that the impetus of the request is that if you start from an expression like nameof(foo.bar) to get to "bar" then if you refactor your code you have a chance that the tool will be able to see the variable expression foo.bar, and process that like other references to the item, and thus be able to change it. Just using the string "bar" would be very hard to see the connection between foo.bar and "bar".
Huh? you only njeed to know the name of something as a string is yuou are doing metaprogramming of some sort -- which is a great feature, but not everyday code. So someone wants this so that they can more easily *refactor* code that isn't very common? I'm betting even more cofused. And no one answered my questions about what it would do in all the, very common cases where an object doesn't ahve a name, opr more than one. More confused than ever...... - CHB -- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
On 2 Feb 2020, at 01:00, Christopher Barker <pythonchb@gmail.com> wrote:
And no one answered my questions about what it would do in all the, very common cases where an object doesn't ahve a name, opr more than one.
This question has been answered multiple times. It's not about the object, it's about the variable. Variables have names. Objects do not as you point out. / Anders
On 01/02/2020 02:48, Richard Damon wrote:
On 1/31/20 9:28 PM, Christopher Barker wrote:
I am really confused by this whole thread:
My understanding is that the impetus of the request is that if you start from an expression like nameof(foo.bar) to get to "bar" then if you refactor your code you have a chance that the tool will be able to see the variable expression foo.bar, and process that like other references to the item, and thus be able to change it. Just using the string "bar" would be very hard to see the connection between foo.bar and "bar".
Maybe I haven't been paying attention but, if accurate, this is the most helpful explanation in the thread. Some sort of conventional mark-up for variable names seems more appropriate than a (pseudo-)function. Possibly something the compiler is made to ignore in strings, but that the IDE treats as identifying a variable name. It would work in comments too. Single quotes do it pretty well, making it a coding standards and IDEs question. Jeff Allen
On 2020-02-02 12:08 p.m., Jeff Allen wrote:
On 01/02/2020 02:48, Richard Damon wrote:
On 1/31/20 9:28 PM, Christopher Barker wrote:
I am really confused by this whole thread:
My understanding is that the impetus of the request is that if you start from an expression like nameof(foo.bar) to get to "bar" then if you refactor your code you have a chance that the tool will be able to see the variable expression foo.bar, and process that like other references to the item, and thus be able to change it. Just using the string "bar" would be very hard to see the connection between foo.bar and "bar".
Maybe I haven't been paying attention but, if accurate, this is the most helpful explanation in the thread.
Some sort of conventional mark-up for variable names seems more appropriate than a (pseudo-)function. Possibly something the compiler is made to ignore in strings, but that the IDE treats as identifying a variable name. It would work in comments too. Single quotes do it pretty well, making it a coding standards and IDEs question.
Hm. Well here's my take: f"{''#foo.}bar" let us have comments in fstrings :p I'd love to have a nameof that errors at runtime tho.
Jeff Allen
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/CDMD4Z... Code of Conduct: http://python.org/psf/codeofconduct/
This would look pretty nice when it would just be used in f-strings. My proposal isn't just about f-strings though. It should also allow developers to get the name of a variable, class, method or function anywhere else.
On 2020-02-02 2:00 p.m., Johan Vergeer wrote:
This would look pretty nice when it would just be used in f-strings.
My proposal isn't just about f-strings though. It should also allow developers to get the name of a variable, class, method or function anywhere else.
where do you want to do it that returning a string isn't good enough? fstrings return a string. they seem perfect for this. or are you trying to say you don't like the extra symbols around it? tbh I don't either. ideally I'd go for f"{#foo.}bar" but oh well, convincing ppl of this is gonna be harder than "just let it have comments" .-. (fwiw, f"{#}Foo" would also be usable, for top-level elements and stuff.)
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/H6ULMW... Code of Conduct: http://python.org/psf/codeofconduct/
participants (8)
-
Alex Hall
-
Anders Hovmöller
-
Christopher Barker
-
Jeff Allen
-
Johan Vergeer
-
Richard Damon
-
Soni L.
-
Steven D'Aprano