I'm not sure about an interpreter, but if you assign a variable, for example:
a symbol is entered into the symbol table and it has the name 'x', an associated memory address, probably off the stack, and the value 7.
So, IMHO, you can't change the variable's name, just it's contents.
You can delete the variable, but then if you use the same name, it might have a different location.
x=3 # different x
print(x) # same result
Jay Matthews what if we can hack into the symbol table or something like that? Until two days ago, I didn't believe it possible to change the "value" of a number. A 5 is a 5. Well, take a look:
why you want to rename a variable?
you can just change it
backspace and then type whatever you want ...
you can rename a variable like a kid shown below...
same output when your print x or y
Kaveis let me try to give you an analogy. In a computer, we can rename a file, and also save a copy of it under a different name. In the second method, the original name still remains (though we can delete it afterwards). I think what LONGTIE is looking for is direct renaming. Reassigning only "transfers the value", like they said quite succinctly.
It's an interesting question. I'm curious to know the answer too. May not be so easy; Python is good at hiding this kind of stuff.
TL;DR: I tried symtable and bytecode (opcode 90: STORE_NAME) to overwrite the name with/without setting the variable's value. Needs more testing/ideas (or, wrong area?)
Yesterday I tried opcode 90* (and omitting the const loaded for it to store) because it takes a name index (so I thought: overwrite name stored there?):
"STORE_NAME(namei) : Implements name = TOS [top of stack]. namei is the index of name in the attribute co_names of the code object. The compiler tries to use STORE_FAST or STORE_GLOBAL if possible."
...but it's fiddly and I've only succeeded in annoying marshal.loads(...modified bytecode...).
import dis, marshal, opcode
#import symtable # needs more looking?
exe=compile('AAA=67;BBB=69', '?', 'exec')
...modding by hand.
Okay, I don't know about LONGTIE, but for me it is purely curiosity. I just want to understand Python better. I have no use for it as of now.
And please read previous answers before posting your own. The assign_and_del method (which isn't exactly renaming) has been suggested quite a few times already.
Yash✳️ your solution is closest to what I was looking for. It's really clever! Thanks a lot for the experiments with locals(). I had totally forgotten about them!
However, it does feel like you're transferring the value and deleting the name at the same time with pop(). And id() is not really a good test for this. In Python, whenever we do a = b, the id of a equals that of b.
But this might be the best we can hope for. Thanks again! 😊
renaming is essentially removing the old name and putting in a new name. in that sense reassigning the variable to a NEW variable name and deleting the old is essentially renaming. Outside of that use a text editor to find all cases of the original name and replace it with the new name. Kishalaya Saha I have to disagree that this method is not "exactly" renaming. It seems to be exactly what it is doing. It reassigned the existing variable to a new name hence renamed.
That said the catch is from the line you delete the old variable You have to make sure not to use that variable name again. It will only exist as a copy in the new variable. If you wanted to change it from the original declaration on then search and replace is the way to go. In this way Kishalaya is right. The del method may not be the most optimal way to achieve this. I guess this is why carefully choosing your names is as important as any other part of your design.
thanx Kishalaya Saha and SlickBack
When we do
a = 1
b = a
Doesn't that mean b will point to the same memory address as that of a?
Because when i use ctypes.addressof to check for their addresses, it's the same.. If, as they said on SO that when we use pop(), it deletes the previous var and then creates new one, then the address of the old and new var should be diff. right? But it's the same
I think, Python doesn't know ahead of time what's on a line, which is which I can swap out the code of a function without changing the function's existence:
Aside from swapping the pointer out from under Python (Kishalaya Saha -- neat; I was wondering if ctypes would work for self-modifying code too), what I think we're trying to do is access Python's name<->memory location mapping table, and change the lookup name. Though I've read "it doesn't work that way", I feel like this should work--the interpreter should just accept it--if a table (managing memory mappings, not the dictionaries in __builtins__) is available.
In-language (i.e., no going behind the curtain) "marshal" felt like the best bet, but I'm afraid it might have to be a dirty hack, because there's the official way...not really working...combined with the reality that marshal.loads()--like PHP's object loader--is definitely not (intended to be) safe so...arbitrary overwrites exist.