Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Grant Edwards via Python-list
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

2024-03-06 Thread dn via Python-list

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

2024-03-06 Thread Roel Schroeven via Python-list




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

2024-03-06 Thread Grant Edwards via Python-list
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

2024-03-06 Thread Roel Schroeven via Python-list

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

2024-03-06 Thread Jacob Kruger via Python-list
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

2024-03-06 Thread Ethan Furman via Python-list

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

2024-03-06 Thread Jacob Kruger via Python-list
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

2024-03-06 Thread Jacob Kruger via Python-list
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

2024-03-06 Thread Jacob Kruger via Python-list
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 

Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Roel Schroeven via Python-list

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

2024-03-06 Thread 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.


--
"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?

2024-03-06 Thread Grant Edwards via Python-list
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

2024-03-06 Thread Thomas Passin via Python-list

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 

Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Thomas Passin via Python-list

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

2024-03-06 Thread Mats Wichmann via Python-list

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

2024-03-06 Thread Jacob Kruger via Python-list
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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Jacob Kruger via Python-list
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 

Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Alan Gauld via Python-list
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