Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
On 2024-03-07, dn via Python-list wrote: > The idea of importing a module into the REPL and then (repeatedly) > manually entering the code to set-up and execute is unusual (surely type > such into a script (once), and run that (repeatedly). As you say, most > of us would be working from an IDE and hitting 'Run'. Am wondering why > you weren't - but it's not important. Unless the code is intended to be used as a module, 'import'ing it into the REPL doesn't make sense. A simple example: ---testit.py-- x = 'x' y = 'y' def foo(): global y print("hi") x = 'X' y = 'Y' print(x) print(y) -- The usual method to play with that interactively is $ python -i testit.py >>> x 'x' >>> y 'y' >>> foo() hi X Y >>> x 'x' >>> y 'Y' >>> As we've seen, doing a 'from testit.py import *' doesn't let you test what the OP was trying to test. Doing 'import testit.py' gets you closer, but it's a hassle to test code that way. The right thing to do is 'python -i ' (or the equivalent button/option in an IDE). https://docs.python.org/3/tutorial/interpreter.html If you intended to use testit.py as a module, and wanted to experiment with its behavior as a module, then go ahead and import it. But, don't do 'from testit.py import *' until 1. you know how that differs from 'import testit.py' and 2. you want to use that difference -- https://mail.python.org/mailman/listinfo/python-list
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
On 7/03/24 05:28, Jacob Kruger via Python-list wrote: ... So, yes, know this comes across like some form of a scam/joke, or list-garbage, since it doesn't make any sense to me at all, but still just wondering if missing something, or should I shift over to 3.12 to see if if works differently, or just try reinstalling 3.11 from scratch, or should I retry the above in something like the VS code console, or a different python console, etc.? Some of the facts, such as HOW the code was being executed were missing (see earlier request for a cut-down scenario, AND reports from others saying 'but it works for me'). The idea of importing a module into the REPL and then (repeatedly) manually entering the code to set-up and execute is unusual (surely type such into a script (once), and run that (repeatedly). As you say, most of us would be working from an IDE and hitting 'Run'. Am wondering why you weren't - but it's not important. That said, the REPL is the perfect place to learn, experiment, and prototype - particularly when compared with the facilities of other language's eco-systems. The entirety of the on-line Tutorial cannot be wrong! (although, after a quick review, I've failed to see where the Tutorial mentions the usual development mode, apart from two very brief asides (the most useful is almost at the very end(?)) - but then (as they say) the objective is to show the language! The lesson-learned is that there are different 'environments' and different ways of building the environment in which the code will run. That's a valuable lesson, and full of subtlety! Glad to see that comparing id()s was useful - for diagnosis but not solution. Other tools might include the locals() and globals() functions. You may also have detected that many of us try to avoid globals and the implicit assumptions about the behavior of mutable collections (eg lists) when treated as 'global'. Then there are "closures", the "LEGB" rule, namespaces, scope, and ... -- -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
Grant Edwards via Python-list schreef op 6/03/2024 om 18:59: On 2024-03-06, Roel Schroeven via Python-list wrote: > Op 6/03/2024 om 17:40 schreef Jacob Kruger via Python-list: >> >>> from scoping2 import * > > [...] > > I would advice not to use 'import *', if at all possible, for multiple > reasons, one of which is to prevent problems like this. Unfortunately, many (most?) tutorials for particular modules (and even example code in the Python documentation itself) are all written assuming that you do "from import *". It saves the tutorial write a few keystrokes, but causes untold trouble for people who learn incorrectly that "from import *" is the proper way to do things. I know ... it's really irritating. -- "There is a theory which states that if ever anyone discovers exactly what the Universe is for and why it is here, it will instantly disappear and be replaced by something even more bizarre and inexplicable. There is another theory which states that this has already happened." -- Douglas Adams, The Restaurant at the End of the Universe -- https://mail.python.org/mailman/listinfo/python-list
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
On 2024-03-06, Roel Schroeven via Python-list wrote: > Op 6/03/2024 om 17:40 schreef Jacob Kruger via Python-list: >> >>> from scoping2 import * > > [...] > > I would advice not to use 'import *', if at all possible, for multiple > reasons, one of which is to prevent problems like this. Unfortunately, many (most?) tutorials for particular modules (and even example code in the Python documentation itself) are all written assuming that you do "from import *". It saves the tutorial write a few keystrokes, but causes untold trouble for people who learn incorrectly that "from import *" is the proper way to do things. > I would also advice not to use global variables from other modules > directly, and in fact would advice to minimize the use of globals in > general as much as possible. If you need to keep state between > methods, it might be better to use a class. -- https://mail.python.org/mailman/listinfo/python-list
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
Op 6/03/2024 om 17:40 schreef Jacob Kruger via Python-list: >>> from scoping2 import * Ah yes, that explains what's happening. After that statement, the name dt_expiry in the current namespace is bound to the same object that the name dt_expiry in the namespace of module scoping2 is bound to. Function do_it re-binds that last one to a new one, with the new value; name dt_expiry in the current namespace is still bound to the old object. (If all of that sounds like gibberish, have a look at "Facts and myths about Python names and values" (text: https://nedbatchelder.com/text/names.html; slides and video: https://nedbatchelder.com/text/names1.html) I would advice not to use 'import *', if at all possible, for multiple reasons, one of which is to prevent problems like this. I would also advice not to use global variables from other modules directly, and in fact would advice to minimize the use of globals in general as much as possible. If you need to keep state between methods, it might be better to use a class. -- "There is a theory which states that if ever anyone discovers exactly what the Universe is for and why it is here, it will instantly disappear and be replaced by something even more bizarre and inexplicable. There is another theory which states that this has already happened." -- Douglas Adams, The Restaurant at the End of the Universe -- https://mail.python.org/mailman/listinfo/python-list
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
Ok, Ethan, that makes sense - I generally work with modules in folders, etc., but, this was just test code, but, 'see' if I instead import scoping2 as sc2, and then refer to sc2.dt_expiry and sc2.do_it, then it does operate as it should - thanks, again. Jacob Kruger +2782 413 4791 "Resistance is futile!...Acceptance is versatile..." On 2024/03/06 18:57, Ethan Furman via Python-list wrote: On 3/6/24 08:28, Jacob Kruger via Python-list wrote: > C:\temp\py_try>python > Python 3.11.7 (tags/v3.11.7:fa7a6f2, Dec 4 2023, 19:24:49) [MSC v.1937 64 bit (AMD64)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> from scoping2 import * And it becomes clear: only do `from ... import *` when the module has been specifically designed to support that. If you were to also do `import scoping2` and, after calling `do_it()`, `print(scoping2.dt_expiry)`, you would see that it had changed. I know there are good explanations for how variables and names work in Python, but I couldn't find any at the moment. Sorry. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
On 3/6/24 08:28, Jacob Kruger via Python-list wrote: > C:\temp\py_try>python > Python 3.11.7 (tags/v3.11.7:fa7a6f2, Dec 4 2023, 19:24:49) [MSC v.1937 64 bit (AMD64)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> from scoping2 import * And it becomes clear: only do `from ... import *` when the module has been specifically designed to support that. If you were to also do `import scoping2` and, after calling `do_it()`, `print(scoping2.dt_expiry)`, you would see that it had changed. I know there are good explanations for how variables and names work in Python, but I couldn't find any at the moment. Sorry. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
You'll see more details in other mail, but, here I am firing up standard python interpreter from within windows terminal, and then executing following line: from scoping2 import * And, this is under windows 11 windows terminal, which is where I generally interact with my python code, via command line - generally working with flask, and/or other forms of command line interaction, most of the time. Jacob Kruger +2782 413 4791 "Resistance is futile!...Acceptance is versatile..." On 2024/03/06 17:39, Roel Schroeven via Python-list wrote: Op 6/03/2024 om 13:55 schreef Jacob Kruger via Python-list: If you import the contents of that file into the python interpreter, [...] What exactly to you mean by "import the contents of that file into the python interpreter"? Other people have put your code in a script, executed it, and saw it working as expected. I pasted in IPython, and likewise saw it working as expected, and the same with IDLE. It seems to me you must be doing something different from us; maybe the way you execute that code might be the key to this whole confusion. -- https://mail.python.org/mailman/listinfo/python-list
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
Matt, other mail is more relevant - seems to maybe have more to do with different behavour if import code, or not - no, does not make sense to me - but, here's the command line contents including printing out id() results, but, only working via importing code: #---start session--- C:\temp\py_try>type scoping2.py from datetime import datetime, timezone, timedelta dt_expiry = datetime.strptime("1970-01-01 00:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc) def do_it(): global dt_expiry dt_expiry = datetime.now()+timedelta(minutes=5) print("date value", dt_expiry.strftime("%Y-%m-%d %H:%M")) print("ID", id(dt_expiry)) # end of do_it function C:\temp\py_try>python Python 3.11.7 (tags/v3.11.7:fa7a6f2, Dec 4 2023, 19:24:49) [MSC v.1937 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> from scoping2 import * >>> print(dt_expiry) 1970-01-01 00:00:00+00:00 >>> print(id(dt_expiry)) 1808577867152 >>> do_it() date value 2024-03-06 18:39 ID 1808572660736 >>> print(dt_expiry) 1970-01-01 00:00:00+00:00 >>> print(id(dt_expiry)) 1808577867152 >>> ---end session--- As in, the two different ID values are being returned outside and inside the function, whereas, if I included that bit inside the interpreter while typing code manually, chances are the same ID would be retained both inside and outside function. Jacob Kruger +2782 413 4791 "Resistance is futile!...Acceptance is versatile..." On 2024/03/06 15:57, Mats Wichmann via Python-list wrote: On 3/6/24 05:55, Jacob Kruger via Python-list wrote: Ok, simpler version - all the code in a simpler test file, and working with two separate variables to explain exactly what am talking about: If you import the contents of that file into the python interpreter, dt_expiry will start off as "1970-01-01 00:00", and, if you execute do_it function, it will print out the new value assigned to the dt_expiry variable inside that function, but if you then again check the value of the dt_expiry variable afterwards, it's reverted to the 1970... value? If I take out the line that removes values from l_test # l_test.clear() # before appending new value to it, then it will also not retain it's new/additional child items after the function exits, and will just revert back to [1, 2, 3] each and every time. In other words, with some of the variable/object types, if you use a function that manipulates the contents of a variable, before then re-assigning it a new value, it seems like it might then actually update/manipulate the global variable, but, either just calling purely content retrieval functions against said objects, or assigning them new values from scratch seems to then ignore the global scope specified in the first line inside the function? Hope this makes more sense No, it doesn't. Your code is working as one would expect. For example, adding prints for the l_test variable, and removing the .clear() which you claim makes it not work, shows me: before: l_test=[1, 2, 3], id(l_test)=140153285385856 leaving do_it: l_test=[1, 2, 3, 1, 2, 3, 99], id(l_test)=140153285385856 after: l_test=[1, 2, 3, 1, 2, 3, 99], id(l_test)=140153285385856 It's the same list object, as you can see by the id values. And the list is updating as expected. And... you don't need the global statement for l_test. As it's mutable, you can mutate it in the function; the global only acts on assignment. Using "global" for that may make your intent more clear to readers though, although static checkers will grumble at you. You must be doing something additional that you're not telling us about. -- https://mail.python.org/mailman/listinfo/python-list
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
Thanks for all your input people, and, yes, I know that besides the scope oddities the rest of the code is not my normal style either - was partly due to forms of experimentation to try figure out what could be causing issues. For example, instead of [:] syntax, was specifically using copy() to make sure was not interacting with original variable values, etc. This will be a bit longer - copying-pasting command line output here to show you what I truly mean - first session, where I am importing code into interpreter and second session where I retype exact same code behave differently: #---first session--- C:\temp\py_try>type scoping2.py from datetime import datetime, timezone, timedelta dt_expiry = datetime.strptime("1970-01-01 00:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc) def do_it(): global dt_expiry dt_expiry = datetime.now()+timedelta(minutes=5) print(dt_expiry.strftime("%Y-%m-%d %H:%M")) # end of do_it function C:\temp\py_try>python Python 3.11.7 (tags/v3.11.7:fa7a6f2, Dec 4 2023, 19:24:49) [MSC v.1937 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> from scoping2 import * >>> print(dt_expiry) 1970-01-01 00:00:00+00:00 >>> do_it() 2024-03-06 18:12 >>> print(dt_expiry) 1970-01-01 00:00:00+00:00 >>> #---end first session--- And, if I now retype the contents of the file into the python interpreter instead: #---start second session--- C:\temp\py_try>python Python 3.11.7 (tags/v3.11.7:fa7a6f2, Dec 4 2023, 19:24:49) [MSC v.1937 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> from datetime import datetime, timezone, timedelta >>> dt_expiry = datetime.strptime("1970-01-01 00:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc) >>> def do_it(): ... global dt_expiry ... dt_expiry = datetime.now()+timedelta(minutes=5) ... print(dt_expiry.strftime("%Y-%m-%d %H:%M")) ... >>> print(dt_expiry) 1970-01-01 00:00:00+00:00 >>> do_it() 2024-03-06 18:20 >>> print(dt_expiry) 2024-03-06 18:20:03.909825 >>> #---end second session--- So, in the second session, where retyped everything, it behaves as I would expect it to, but, during first session, the variable is being treated as a local variable inside the function - no code differences since literally copied-pasted each and every line into console, but, a different behaviour nonetheless? So, yes, know this comes across like some form of a scam/joke, or list-garbage, since it doesn't make any sense to me at all, but still just wondering if missing something, or should I shift over to 3.12 to see if if works differently, or just try reinstalling 3.11 from scratch, or should I retry the above in something like the VS code console, or a different python console, etc.? Sorry Jacob Kruger Jacob Kruger +2782 413 4791 "Resistance is futile!...Acceptance is versatile..." On 2024/03/06 16:01, Thomas Passin via Python-list wrote: On 3/6/2024 7:55 AM, Jacob Kruger via Python-list wrote: Ok, simpler version - all the code in a simpler test file, and working with two separate variables to explain exactly what am talking about: # start code from datetime import datetime, timezone, timedelta from copy import copy # initialise original values dt_expiry = datetime.strptime("1970-01-01 00:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc) l_test = [1, 2, 3] def do_it(): global dt_expiry, l_test # asked python to refer to global variables for both # assign new value immediately dt_expiry = datetime.now()+timedelta(minutes=5) print(dt_expiry.strftime("%Y-%m-%d %H:%M")) # just to show new value has been assigned # grab copy of list for re-use of items l_temp = copy(l_test) # following line means l_test will later on retain value in global scope because it was manipulated inside function instead of just assigned new value l_test.clear() # replace original set of values for i in l_temp: l_test.append(i) # add new item l_test.append(99) # end of do_it function # end code If you import the contents of that file into the python interpreter, dt_expiry will start off as "1970-01-01 00:00", and, if you execute do_it function, it will print out the new value assigned to the dt_expiry variable inside that function, but if you then again check the value of the dt_expiry variable afterwards, it's reverted to the 1970... value? Not when I run your code. With a little annotation added to the print statements I get (I added the import statements to make it run, and I used the same date-time formatting for all three print statements): List before: [1, 2, 3] start: 1970-01-01 00:00 inside after reassignment: 2024-03-06 08:57 outside after: 2024-03-06 08:57 List after: [1, 2, 3, 99] As an aside, you have gone to some trouble to copy, clear, and reconstruct l_test. It would be simpler like this (and you wouldn't have to impor
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
Op 6/03/2024 om 16:39 schreef Roel Schroeven via Python-list: Op 6/03/2024 om 13:55 schreef Jacob Kruger via Python-list: If you import the contents of that file into the python interpreter, [...] What exactly to you mean by "import the contents of that file into the python interpreter"? Other people have put your code in a script, executed it, and saw it working as expected. I pasted in IPython, and likewise saw it working as expected, and the same with IDLE. It seems to me you must be doing something different from us; maybe the way you execute that code might be the key to this whole confusion. (As an aside, I made a type; "What exactly _do_ you mean" is what I meant to type) If you want, you can play with the code online here: https://tio.run/##pVPbitswEH3XVwwJITaNQ9KllATy0EKhL/2AUsqiWKNkWlkykrzZ7NJvT0e@JWT7VmPsEZozc87RqD7Ho7MPl8sUQpQ@QukUCqG9q0DJiJEqBKpqx1vDegHp@@JsHyk0UfaY0tXnIT/FQogpkKVI0lBAcJ4OZKWBJ2kaDEKo@IjPNfkz7MYGyxB9nYJsst58XBWrNb@wWm1Xq8kCJrPvxawqZgpmX7ezb5N86bE2ssQsvpDVbjewWzaxzIUwjxFD5PI/1gt4v4CHn0xKoQblHilm@VYAPwfj9kxrpLOAHjcFGX6jgrp1CqIDjxp9CnrMk/Qk9wYDaOdh7@JRtCUTMtDBgsVTp5edYbuIZZpzl/NP@dadsvzdaG1WkW2Yy@5D3mJqTzZmIzK5pTu37p3JmcOvhkUw2XB0pxsmRxlgj2h7jqh6ygcv990pOg18ZLEV5bFo0ulpoIhVaHOTP1XNvFN21rmV91W0M8adyB64hEWoUNowGHoiY8CwVg/sp8coyQ722MHTwEWRCZYy9SVGMd9KWqqbBFWcGkgh6MaWkbgOryNKlSi2igdZV8kj6RCXpUHps4FtPz/X4QwYU6F@RlNSMoESv071digk6xqtymgoJVXXMdl027DP22xyvg8cpfLt/I0KRL@RLiDwhHanPP@M3Brn@bAu2mdc6/k4B7vXMfxzs98R2L12/@tOPrb48owlz1fH575TMTbsr8sb@CfNR3kH@x9@l8tf (sorry for the long URL; that's where tio.run puts the code) Again it works as expected, but with or without the l_test.clear() line. -- "Il semble que la perfection soit atteinte non quand il n'y a plus rien à ajouter, mais quand il n'y a plus rien à retrancher." "Perfectie is niet bereikt als er niets meer toe te voegen is, maar als er niets meer weg te nemen is." -- Antoine de Saint-Exupéry -- https://mail.python.org/mailman/listinfo/python-list
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
Op 6/03/2024 om 13:55 schreef Jacob Kruger via Python-list: If you import the contents of that file into the python interpreter, [...] What exactly to you mean by "import the contents of that file into the python interpreter"? Other people have put your code in a script, executed it, and saw it working as expected. I pasted in IPython, and likewise saw it working as expected, and the same with IDLE. It seems to me you must be doing something different from us; maybe the way you execute that code might be the key to this whole confusion. -- "Il semble que la perfection soit atteinte non quand il n'y a plus rien à ajouter, mais quand il n'y a plus rien à retrancher." "Perfectie is niet bereikt als er niets meer toe te voegen is, maar als er niets meer weg te nemen is." -- Antoine de Saint-Exupéry -- https://mail.python.org/mailman/listinfo/python-list
Re: Can u help me?
On 2024-03-06, MRAB via Python-list wrote: > On 2024-03-06 01:44, Ethan Furman via Python-list wrote: >> On 3/5/24 16:49, MRAB via Python-list wrote: >> > On 2024-03-06 00:24, Ethan Furman via Python-list wrote: >> >> On 3/5/24 16:06, Chano Fucks via Python-list wrote: >> >> >> >>> [image: image.png] >> >> >> >> The image is of MS-Windows with the python installation window of >> "Repair Successful". Hopefully somebody better at >> >> explaining that problem can take it from here... >> >> >> > If the repair was successful, what's the problem? >> >> I imagine the issue is trying get Python to run (as I recall, the python >> icon on the MS-Windows desktop is the >> installer, not Python itself). > > There was an issue 3 years ago about renaming the installer for clarity: > > https://github.com/python/cpython/issues/87322 Yea, this problem comes up constantly (and has for many years). People have suggested renaming the installer so it has "setup" or "install" in the name. People have suggested adding text to the installer splash screen to explain that it's the installer and not python itself, that you already have python installed, and if you want to _run_ python instead of _install_ python, here's how. People have suggested having the installer remove itself by default when it's done installing. People have suggested lots of solutions. AFAICT, nobody has actually done anything. -- https://mail.python.org/mailman/listinfo/python-list
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
On 3/6/2024 7:55 AM, Jacob Kruger via Python-list wrote: Ok, simpler version - all the code in a simpler test file, and working with two separate variables to explain exactly what am talking about: # start code from datetime import datetime, timezone, timedelta from copy import copy # initialise original values dt_expiry = datetime.strptime("1970-01-01 00:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc) l_test = [1, 2, 3] def do_it(): global dt_expiry, l_test # asked python to refer to global variables for both # assign new value immediately dt_expiry = datetime.now()+timedelta(minutes=5) print(dt_expiry.strftime("%Y-%m-%d %H:%M")) # just to show new value has been assigned # grab copy of list for re-use of items l_temp = copy(l_test) # following line means l_test will later on retain value in global scope because it was manipulated inside function instead of just assigned new value l_test.clear() # replace original set of values for i in l_temp: l_test.append(i) # add new item l_test.append(99) # end of do_it function # end code If you import the contents of that file into the python interpreter, dt_expiry will start off as "1970-01-01 00:00", and, if you execute do_it function, it will print out the new value assigned to the dt_expiry variable inside that function, but if you then again check the value of the dt_expiry variable afterwards, it's reverted to the 1970... value? Not when I run your code. With a little annotation added to the print statements I get (I added the import statements to make it run, and I used the same date-time formatting for all three print statements): List before: [1, 2, 3] start: 1970-01-01 00:00 inside after reassignment: 2024-03-06 08:57 outside after: 2024-03-06 08:57 List after: [1, 2, 3, 99] As an aside, you have gone to some trouble to copy, clear, and reconstruct l_test. It would be simpler like this (and you wouldn't have to import the "copy" library): l_temp = l_test[:] l_test = [] Instead of those lines and then this: for i in l_temp: l_test.append(i) you could achieve the same thing with this single statement: l_test = l_test[:] If I take out the line that removes values from l_test # l_test.clear() # before appending new value to it, then it will also not retain it's new/additional child items after the function exits, and will just revert back to [1, 2, 3] each and every time. In other words, with some of the variable/object types, if you use a function that manipulates the contents of a variable, before then re-assigning it a new value, it seems like it might then actually update/manipulate the global variable, but, either just calling purely content retrieval functions against said objects, or assigning them new values from scratch seems to then ignore the global scope specified in the first line inside the function? Hope this makes more sense Jacob Kruger +2782 413 4791 "Resistance is futile!...Acceptance is versatile..." On 2024/03/05 20:23, dn via Python-list wrote: Jacob, Please reduce the problem to a small code-set which reproduces the problem. If we can reproduce same, then that tells us something. At the very least, we can experiment without having to expend amounts of time in a (likely faulty) bid to reproduce the same environment. Also, code is the ultimate description! Perhaps start with a small experiment: - after l_servers is created, print its id() - after the global statement, print its id() - after the clear/reassignment, print its id() Is Python always working with the same list? Please advise... On 6/03/24 07:13, Jacob Kruger via Python-list wrote: Hi there Working with python 3.11, and, issue that confused me for a little while, trying to figure out what was occurring - unless am completely confused, or missing something - was that, for example, when having pre-defined a variable, and then included it in the global statement inside a function, that function was still referring to a completely local instance, without manipulating outside variable object at all unless I first executed a form of referral to it, before then possibly assigning a new value to it. Now, this does not seem to occur consistently if, for example, I just run bare-bones test code inside the python interpreter, but consistently occurs inside my actual testing script. Basically, in a file with python code in that am using for a form of testing at the moment, at the top of the file, under all the import statements, I initiate the existence of a list variable to make use of later: # code snippet l_servers = [] # end of first code snippet Then, lower down, inside a couple of different functions, the first line inside the functions includes the following: # code snippet global l_servers # end code snippet That should, in theory, mean that if I assign a value to that variable inside one of t
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
On 3/6/2024 5:59 AM, Alan Gauld via Python-list wrote: On 05/03/2024 22:46, Grant Edwards via Python-list wrote: Unfortunately (presumably thanks to SEO) the enshittification of Google has reached the point where searching for info on things like Python name scope, the first page of links are to worthless sites like geeksforgeeks. And not just Google, I just tried bing, yahoo and duckduckgo and they are all the same. Not a one listed anything from python.org on the first page... In fact it didn't even appear in the first 100 listings, although wikipedia did manage an entry, eventually. I don't know ... I just searched for "python local vs global variables" and a python.org page on it was the second hit. I usually use StartPage - who knows where they aggregate from - but the same search on Google and Bing also popped up the python.org link as the second hit. As usual Bing was a nasty experience, though. Still, if your search phrase isn't as well focused as that or you are less lucky, for sure you'll get all sorts of junk. -- https://mail.python.org/mailman/listinfo/python-list
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
On 3/6/24 05:55, Jacob Kruger via Python-list wrote: Ok, simpler version - all the code in a simpler test file, and working with two separate variables to explain exactly what am talking about: If you import the contents of that file into the python interpreter, dt_expiry will start off as "1970-01-01 00:00", and, if you execute do_it function, it will print out the new value assigned to the dt_expiry variable inside that function, but if you then again check the value of the dt_expiry variable afterwards, it's reverted to the 1970... value? If I take out the line that removes values from l_test # l_test.clear() # before appending new value to it, then it will also not retain it's new/additional child items after the function exits, and will just revert back to [1, 2, 3] each and every time. In other words, with some of the variable/object types, if you use a function that manipulates the contents of a variable, before then re-assigning it a new value, it seems like it might then actually update/manipulate the global variable, but, either just calling purely content retrieval functions against said objects, or assigning them new values from scratch seems to then ignore the global scope specified in the first line inside the function? Hope this makes more sense No, it doesn't. Your code is working as one would expect. For example, adding prints for the l_test variable, and removing the .clear() which you claim makes it not work, shows me: before: l_test=[1, 2, 3], id(l_test)=140153285385856 leaving do_it: l_test=[1, 2, 3, 1, 2, 3, 99], id(l_test)=140153285385856 after: l_test=[1, 2, 3, 1, 2, 3, 99], id(l_test)=140153285385856 It's the same list object, as you can see by the id values. And the list is updating as expected. And... you don't need the global statement for l_test. As it's mutable, you can mutate it in the function; the global only acts on assignment. Using "global" for that may make your intent more clear to readers though, although static checkers will grumble at you. You must be doing something additional that you're not telling us about. -- https://mail.python.org/mailman/listinfo/python-list
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
So, this does not make sense to me in terms of the following snippet from the official python docs page: https://docs.python.org/3/faq/programming.html "In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global." So, I would then assume that if I explicitly include a variable name inside the global statement, then even just assigning it a new value should update the variable in the global context, outside the function? Unless this is something that changed from 3.11 to 3.12 - since that snippet is more or less referring to 3.12, but, don't think it was changed in any way? Jacob Kruger +2782 413 4791 "Resistance is futile!...Acceptance is versatile..." On 2024/03/06 14:55, Jacob Kruger wrote: Ok, simpler version - all the code in a simpler test file, and working with two separate variables to explain exactly what am talking about: # start code from datetime import datetime, timezone, timedelta from copy import copy # initialise original values dt_expiry = datetime.strptime("1970-01-01 00:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc) l_test = [1, 2, 3] def do_it(): global dt_expiry, l_test # asked python to refer to global variables for both # assign new value immediately dt_expiry = datetime.now()+timedelta(minutes=5) print(dt_expiry.strftime("%Y-%m-%d %H:%M")) # just to show new value has been assigned # grab copy of list for re-use of items l_temp = copy(l_test) # following line means l_test will later on retain value in global scope because it was manipulated inside function instead of just assigned new value l_test.clear() # replace original set of values for i in l_temp: l_test.append(i) # add new item l_test.append(99) # end of do_it function # end code If you import the contents of that file into the python interpreter, dt_expiry will start off as "1970-01-01 00:00", and, if you execute do_it function, it will print out the new value assigned to the dt_expiry variable inside that function, but if you then again check the value of the dt_expiry variable afterwards, it's reverted to the 1970... value? If I take out the line that removes values from l_test # l_test.clear() # before appending new value to it, then it will also not retain it's new/additional child items after the function exits, and will just revert back to [1, 2, 3] each and every time. In other words, with some of the variable/object types, if you use a function that manipulates the contents of a variable, before then re-assigning it a new value, it seems like it might then actually update/manipulate the global variable, but, either just calling purely content retrieval functions against said objects, or assigning them new values from scratch seems to then ignore the global scope specified in the first line inside the function? Hope this makes more sense Jacob Kruger +2782 413 4791 "Resistance is futile!...Acceptance is versatile..." On 2024/03/05 20:23, dn via Python-list wrote: Jacob, Please reduce the problem to a small code-set which reproduces the problem. If we can reproduce same, then that tells us something. At the very least, we can experiment without having to expend amounts of time in a (likely faulty) bid to reproduce the same environment. Also, code is the ultimate description! Perhaps start with a small experiment: - after l_servers is created, print its id() - after the global statement, print its id() - after the clear/reassignment, print its id() Is Python always working with the same list? Please advise... On 6/03/24 07:13, Jacob Kruger via Python-list wrote: Hi there Working with python 3.11, and, issue that confused me for a little while, trying to figure out what was occurring - unless am completely confused, or missing something - was that, for example, when having pre-defined a variable, and then included it in the global statement inside a function, that function was still referring to a completely local instance, without manipulating outside variable object at all unless I first executed a form of referral to it, before then possibly assigning a new value to it. Now, this does not seem to occur consistently if, for example, I just run bare-bones test code inside the python interpreter, but consistently occurs inside my actual testing script. Basically, in a file with python code in that am using for a form of testing at the moment, at the top of the file, under all the import statements, I initiate the existence of a list variable to make use of later: # code snippet l_servers = [] # end of first code snippet Then, lower down, inside a couple of different functions, the first line inside the functions includes the following: # code snippet global l_servers # end code snippet That
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
Ok, simpler version - all the code in a simpler test file, and working with two separate variables to explain exactly what am talking about: # start code from datetime import datetime, timezone, timedelta from copy import copy # initialise original values dt_expiry = datetime.strptime("1970-01-01 00:00", "%Y-%m-%d %H:%M").replace(tzinfo=timezone.utc) l_test = [1, 2, 3] def do_it(): global dt_expiry, l_test # asked python to refer to global variables for both # assign new value immediately dt_expiry = datetime.now()+timedelta(minutes=5) print(dt_expiry.strftime("%Y-%m-%d %H:%M")) # just to show new value has been assigned # grab copy of list for re-use of items l_temp = copy(l_test) # following line means l_test will later on retain value in global scope because it was manipulated inside function instead of just assigned new value l_test.clear() # replace original set of values for i in l_temp: l_test.append(i) # add new item l_test.append(99) # end of do_it function # end code If you import the contents of that file into the python interpreter, dt_expiry will start off as "1970-01-01 00:00", and, if you execute do_it function, it will print out the new value assigned to the dt_expiry variable inside that function, but if you then again check the value of the dt_expiry variable afterwards, it's reverted to the 1970... value? If I take out the line that removes values from l_test # l_test.clear() # before appending new value to it, then it will also not retain it's new/additional child items after the function exits, and will just revert back to [1, 2, 3] each and every time. In other words, with some of the variable/object types, if you use a function that manipulates the contents of a variable, before then re-assigning it a new value, it seems like it might then actually update/manipulate the global variable, but, either just calling purely content retrieval functions against said objects, or assigning them new values from scratch seems to then ignore the global scope specified in the first line inside the function? Hope this makes more sense Jacob Kruger +2782 413 4791 "Resistance is futile!...Acceptance is versatile..." On 2024/03/05 20:23, dn via Python-list wrote: Jacob, Please reduce the problem to a small code-set which reproduces the problem. If we can reproduce same, then that tells us something. At the very least, we can experiment without having to expend amounts of time in a (likely faulty) bid to reproduce the same environment. Also, code is the ultimate description! Perhaps start with a small experiment: - after l_servers is created, print its id() - after the global statement, print its id() - after the clear/reassignment, print its id() Is Python always working with the same list? Please advise... On 6/03/24 07:13, Jacob Kruger via Python-list wrote: Hi there Working with python 3.11, and, issue that confused me for a little while, trying to figure out what was occurring - unless am completely confused, or missing something - was that, for example, when having pre-defined a variable, and then included it in the global statement inside a function, that function was still referring to a completely local instance, without manipulating outside variable object at all unless I first executed a form of referral to it, before then possibly assigning a new value to it. Now, this does not seem to occur consistently if, for example, I just run bare-bones test code inside the python interpreter, but consistently occurs inside my actual testing script. Basically, in a file with python code in that am using for a form of testing at the moment, at the top of the file, under all the import statements, I initiate the existence of a list variable to make use of later: # code snippet l_servers = [] # end of first code snippet Then, lower down, inside a couple of different functions, the first line inside the functions includes the following: # code snippet global l_servers # end code snippet That should, in theory, mean that if I assign a value to that variable inside one of the functions, it should reflect globally? However, it seems like that, while inside those functions, it can be assigned a new list of values, but if I then return to the scope outside the functions, it has reverted back to being an empty list = []? The issue seems to specifically (or not) occur when I make a call to one function, and, in the steps it's executing in one context, while it's not doing anything to the list directly, it's then making a call to the second function, which is then meant to repopulate the list with a brand new set of values. Now, what almost seems to be occurring, is that while just manipulating the contents of a referenced variable is fine in this context, the moment I try to reassign it, that's where the issue is occurring . Here are relevant excerpts fr
Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference
On 05/03/2024 22:46, Grant Edwards via Python-list wrote: > Unfortunately (presumably thanks to SEO) the enshittification of > Google has reached the point where searching for info on things like > Python name scope, the first page of links are to worthless sites like > geeksforgeeks. And not just Google, I just tried bing, yahoo and duckduckgo and they are all the same. Not a one listed anything from python.org on the first page... In fact it didn't even appear in the first 100 listings, although wikipedia did manage an entry, eventually. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos -- https://mail.python.org/mailman/listinfo/python-list