Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #52628 > unrolled thread
| Started by | tmellman@googlemail.com |
|---|---|
| First post | 2013-08-17 07:25 -0700 |
| Last post | 2013-08-20 11:14 +1000 |
| Articles | 20 on this page of 27 — 9 participants |
Back to article view | Back to comp.lang.python
Importing variables non-deterministic? tmellman@googlemail.com - 2013-08-17 07:25 -0700
Re: Importing variables non-deterministic? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-08-17 15:01 +0000
Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 09:14 +0200
Re: Importing variables non-deterministic? Dave Angel <davea@davea.name> - 2013-08-19 07:45 +0000
Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 10:16 +0200
Re: Importing variables non-deterministic? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-08-19 16:57 +0000
Re: Importing variables non-deterministic? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-08-19 17:16 +0000
Re: Importing variables non-deterministic? Chris Angelico <rosuav@gmail.com> - 2013-08-19 18:25 +0100
Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 19:40 +0200
Re: Importing variables non-deterministic? Chris Angelico <rosuav@gmail.com> - 2013-08-19 09:32 +0100
Re: Importing variables non-deterministic? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-08-19 17:05 +0000
Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 22:34 +0200
Re: Importing variables non-deterministic? Steven D'Aprano <steve@pearwood.info> - 2013-08-20 05:48 +0000
Re: Importing variables non-deterministic? wxjmfauth@gmail.com - 2013-08-19 23:40 -0700
Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-20 08:55 +0200
Re: Importing variables non-deterministic? wxjmfauth@gmail.com - 2013-08-20 00:31 -0700
Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-20 09:55 +0200
Re: Importing variables non-deterministic? wxjmfauth@gmail.com - 2013-08-20 02:15 -0700
Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 11:03 +0200
Re: Importing variables non-deterministic? Chris Angelico <rosuav@gmail.com> - 2013-08-19 10:18 +0100
Re: Importing variables non-deterministic? Peter Otten <__peter__@web.de> - 2013-08-19 11:49 +0200
Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 13:54 +0200
Re: Importing variables non-deterministic? Dave Angel <davea@davea.name> - 2013-08-19 12:33 +0000
Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 16:55 +0200
Re: Importing variables non-deterministic? Chris Angelico <rosuav@gmail.com> - 2013-08-19 16:04 +0100
Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 19:25 +0200
Re: Importing variables non-deterministic? Ben Finney <ben+python@benfinney.id.au> - 2013-08-20 11:14 +1000
Page 1 of 2 [1] 2 Next page →
| From | tmellman@googlemail.com |
|---|---|
| Date | 2013-08-17 07:25 -0700 |
| Subject | Importing variables non-deterministic? |
| Message-ID | <a75383ec-b363-4ad4-9703-ca5d8ea614df@googlegroups.com> |
I have this file that has this:
from struct_global import y
from struct_global import x
and this usage (a few lines later in a class method definition in the same file):
if y == x:
If I stop there in pdb, I can observe this:
(Pdb) p x
66
(Pdb) p y
-1
(Pdb) from struct_global import y
(Pdb) p y
62
How did my first import get hidden? Is there any way to see where a variable resolves to?
[toc] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-08-17 15:01 +0000 |
| Message-ID | <520f9054$0$30000$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #52628 |
On Sat, 17 Aug 2013 07:25:43 -0700, tmellman wrote: > I have this file that has this: > > from struct_global import y > from struct_global import x The import of x appears to be irrelevant, so I'll ignore it. Here you import y from the struct_global module. This creates a new name y in the current module. y is bound to the same object that struct_global.y happens to be at the moment of the import, but y is *not* a reference to the *name* struct_global.y. This means that the two names, "y in current module" and "y in struct_global module" point to the same object, but they aren't two aliases for the same variable. They are different variables that just happen to share the same value (an object). If the object mutates (which ints cannot do), then both "y"s will see the change (naturally, since both refer to the same object). But if either name is rebound to a different object, the other name is unaffected. We can see the same behaviour locally, without an import, by doing this: py> x = [1] py> y = x # y is bound to the same object as x py> print(y) [1] py> x.append(2) # mutate x in place py> print(y) [1, 2] py> x = [1, 2, 3] # re-bind x to a new object py> print(y) # y still bound to the first object [1, 2] "from struct_globals import y" is a binding operation, no different from "y = something". > and this usage (a few lines later in a class method definition in the > same file): > > if y == x: > > If I stop there in pdb, I can observe this: > > (Pdb) p x > 66 > (Pdb) p y > -1 > (Pdb) from struct_global import y > (Pdb) p y > 62 And here you re-import the name "y" from struct_global. That rebinds the current module's "y" with whatever value struct_global.y has *now*, rather than a second (or a minute, or an hour) earlier when the first import took place. Obviously at some point between the first import and the second import, struct_global.y must have been reassigned from -1 to 62. This goes to show why global variables are considered harmful, and why clean, modern program design tries to reduce the use of them as much as possible. Global variables are too easily modified by, well, *anything*. The sort of behaviour you are seeing is sometimes called "action at a distance" -- something, anything, anywhere in your program, possibly buried deep, deep down inside some function you might never suspect, is changing the global variable. > How did my first import get hidden? You reassigned to it. "from struct_global import y" is practically syntactic sugar for this: import struct_global y = struct_global.y > Is there any way to see where a > variable resolves to? You just did. You inspected the variable "y", and you saw that it is assigned the value 62. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2013-08-19 09:14 +0200 |
| Message-ID | <mailman.13.1376896513.19984.python-list@python.org> |
| In reply to | #52630 |
Op 17-08-13 17:01, Steven D'Aprano schreef: > > And here you re-import the name "y" from struct_global. That rebinds the > current module's "y" with whatever value struct_global.y has *now*, > rather than a second (or a minute, or an hour) earlier when the first > import took place. Obviously at some point between the first import and > the second import, struct_global.y must have been reassigned from -1 to > 62. > > This goes to show why global variables are considered harmful, and why > clean, modern program design tries to reduce the use of them as much as > possible. Global variables are too easily modified by, well, *anything*. > The sort of behaviour you are seeing is sometimes called "action at a > distance" -- something, anything, anywhere in your program, possibly > buried deep, deep down inside some function you might never suspect, is > changing the global variable. I think you are overstating your case. Classes and functions are variables too and in general nobody seems to have a problem with them being global. -- Antoon Pardon
[toc] | [prev] | [next] | [standalone]
| From | Dave Angel <davea@davea.name> |
|---|---|
| Date | 2013-08-19 07:45 +0000 |
| Message-ID | <mailman.14.1376898318.19984.python-list@python.org> |
| In reply to | #52630 |
Antoon Pardon wrote: > Op 17-08-13 17:01, Steven D'Aprano schreef: >> >> And here you re-import the name "y" from struct_global. That rebinds the >> current module's "y" with whatever value struct_global.y has *now*, >> rather than a second (or a minute, or an hour) earlier when the first >> import took place. Obviously at some point between the first import and >> the second import, struct_global.y must have been reassigned from -1 to >> 62. >> >> This goes to show why global variables are considered harmful, and why >> clean, modern program design tries to reduce the use of them as much as >> possible. Global variables are too easily modified by, well, *anything*. >> The sort of behaviour you are seeing is sometimes called "action at a >> distance" -- something, anything, anywhere in your program, possibly >> buried deep, deep down inside some function you might never suspect, is >> changing the global variable. > > I think you are overstating your case. Classes and functions are > variables too and in general nobody seems to have a problem with them > being global. > It's global *variables* that are to be avoided. constants like clsases and functions are fine. On the other hand, class attributes can be variable, and thus are to be avoided when reasonable. There *are* places where global variables make sense, such as for caching, or counting. But those are typically hidden, so they are global in lifetime, but not in scope. -- DaveA
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2013-08-19 10:16 +0200 |
| Message-ID | <mailman.16.1376900198.19984.python-list@python.org> |
| In reply to | #52630 |
Op 19-08-13 09:45, Dave Angel schreef: > Antoon Pardon wrote: > >> Op 17-08-13 17:01, Steven D'Aprano schreef: >>> >>> And here you re-import the name "y" from struct_global. That rebinds the >>> current module's "y" with whatever value struct_global.y has *now*, >>> rather than a second (or a minute, or an hour) earlier when the first >>> import took place. Obviously at some point between the first import and >>> the second import, struct_global.y must have been reassigned from -1 to >>> 62. >>> >>> This goes to show why global variables are considered harmful, and why >>> clean, modern program design tries to reduce the use of them as much as >>> possible. Global variables are too easily modified by, well, *anything*. >>> The sort of behaviour you are seeing is sometimes called "action at a >>> distance" -- something, anything, anywhere in your program, possibly >>> buried deep, deep down inside some function you might never suspect, is >>> changing the global variable. >> >> I think you are overstating your case. Classes and functions are >> variables too and in general nobody seems to have a problem with them >> being global. >> > > It's global *variables* that are to be avoided. constants like clsases > and functions are fine. On the other hand, class attributes can be > variable, and thus are to be avoided when reasonable. Python has no constants. Classes and functions can be changed just like any other variable. I agree that classes and function are generally meant to be constant, but often enought so are global int variables. And some of those that do change, only do so in the initialisation phase and should be considered constant for the rest of the program. My point was that Steven has no way of knowing what exactly is going on here and so shouldn't be making such a sweeping statement. -- Antoon Pardon
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-08-19 16:57 +0000 |
| Message-ID | <52124e81$0$29986$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #52677 |
On Mon, 19 Aug 2013 10:16:36 +0200, Antoon Pardon wrote:
> Op 19-08-13 09:45, Dave Angel schreef:
>> Antoon Pardon wrote:
>>
>>> Op 17-08-13 17:01, Steven D'Aprano schreef:
>>>>
>>>> And here you re-import the name "y" from struct_global. That rebinds
>>>> the current module's "y" with whatever value struct_global.y has
>>>> *now*, rather than a second (or a minute, or an hour) earlier when
>>>> the first import took place. Obviously at some point between the
>>>> first import and the second import, struct_global.y must have been
>>>> reassigned from -1 to 62.
>>>>
>>>> This goes to show why global variables are considered harmful, and
>>>> why clean, modern program design tries to reduce the use of them as
>>>> much as possible. Global variables are too easily modified by, well,
>>>> *anything*. The sort of behaviour you are seeing is sometimes called
>>>> "action at a distance" -- something, anything, anywhere in your
>>>> program, possibly buried deep, deep down inside some function you
>>>> might never suspect, is changing the global variable.
>>>
>>> I think you are overstating your case. Classes and functions are
>>> variables too and in general nobody seems to have a problem with them
>>> being global.
>>>
>>>
>> It's global *variables* that are to be avoided. constants like clsases
>> and functions are fine. On the other hand, class attributes can be
>> variable, and thus are to be avoided when reasonable.
>
> Python has no constants. Classes and functions can be changed just like
> any other variable. I agree that classes and function are generally
> meant to be constant, but often enought so are global int variables.
You are technically correct, but missing the point. If I wrote code that
went around reassigning names from one function to another function, I
would very likely soon work myself into a state of utter confusion:
def func(x):
...
# later
save_func = func
func = lambda x, y: do_stuff(x, 3*y)-4
result = something_that_calls_func()
func = save_func
Nasty, horrible code, yes? But it's nasty and horrible because "func" is
bound to a function, it would be equally nasty and horrible if it was a
data type (a string, a list, an int, a flag, ...) instead.
Since classes and functions are First Class objects in Python, naturally
if you treat them as global *variables* rather than global *constants*
you can end up with problems. The problem is not the global part alone.
Global constants, or pseudo-constant-by-convention-only, are fine.
> And some of those that do change, only do so in the initialisation phase
> and should be considered constant for the rest of the program.
>
> My point was that Steven has no way of knowing what exactly is going on
> here and so shouldn't be making such a sweeping statement.
On the contrary, I can read the Original Poster's description of the
problem, and then use my ability to reason to deduce what the most likely
explanation was.
Now of course I might be wrong. I don't claim infallibility or
omniscience. But I'm not an idiot, and if the OP says that a global
variable has one value at one time, and then some time later has a
different value, there are two likely possibilities:
* The variable was changed by some other piece of code, i.e. it
actually was being used as a *global variable*.
* The OP is completely confused, and (inadvertently, we hope)
reporting things which are actually not true.
Much less likely:
* Despite 15+ years of experience with Python, and reading the
documentation, I have failed to notice that, yes, the OP is
correct and importing variables is non-deterministic.
* There's a bug in Python.
Both of these are theoretically possible, but the chance of them is
somewhere between Buckley's and None.
Of course, if you have an alternate explanation for the issue the OP
reported, I would love to hear it. Maybe I have completely misunderstood
the situation.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-08-19 17:16 +0000 |
| Message-ID | <521252f2$0$29986$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #52694 |
On Mon, 19 Aug 2013 16:57:37 +0000, Steven D'Aprano wrote: > def func(x): > ... > > # later > save_func = func > func = lambda x, y: do_stuff(x, 3*y)-4 result = > something_that_calls_func() > func = save_func > > > Nasty, horrible code, yes? But it's nasty and horrible because "func" is > bound to a function, it would be equally nasty and horrible if it was a > data type (a string, a list, an int, a flag, ...) instead. Oops, I left out a word. It is NOT nasty and horrible specifically because "func" is bound to a function, it would be equally horrible if it were a data type. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-08-19 18:25 +0100 |
| Message-ID | <mailman.36.1376933125.19984.python-list@python.org> |
| In reply to | #52698 |
On Mon, Aug 19, 2013 at 6:16 PM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > On Mon, 19 Aug 2013 16:57:37 +0000, Steven D'Aprano wrote: > >> def func(x): >> ... >> >> # later >> save_func = func >> func = lambda x, y: do_stuff(x, 3*y)-4 result = >> something_that_calls_func() >> func = save_func >> >> >> Nasty, horrible code, yes? But it's nasty and horrible because "func" is >> bound to a function, it would be equally nasty and horrible if it was a >> data type (a string, a list, an int, a flag, ...) instead. > > Oops, I left out a word. It is NOT nasty and horrible specifically > because "func" is bound to a function, it would be equally horrible if it > were a data type. I was having a little trouble parsing that! Thank you for the Iolanthe-style[1] update. ChrisA [1] http://math.boisestate.edu/gas/iolanthe/web_op/iol23d.html
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2013-08-19 19:40 +0200 |
| Message-ID | <mailman.38.1376934119.19984.python-list@python.org> |
| In reply to | #52694 |
Op 19-08-13 18:57, Steven D'Aprano schreef: > On Mon, 19 Aug 2013 10:16:36 +0200, Antoon Pardon wrote: > >> Op 19-08-13 09:45, Dave Angel schreef: >>> Antoon Pardon wrote: >>> >>>> Op 17-08-13 17:01, Steven D'Aprano schreef: >>>>> >>>>> And here you re-import the name "y" from struct_global. That rebinds >>>>> the current module's "y" with whatever value struct_global.y has >>>>> *now*, rather than a second (or a minute, or an hour) earlier when >>>>> the first import took place. Obviously at some point between the >>>>> first import and the second import, struct_global.y must have been >>>>> reassigned from -1 to 62. >>>>> >>>>> This goes to show why global variables are considered harmful, and >>>>> why clean, modern program design tries to reduce the use of them as >>>>> much as possible. Global variables are too easily modified by, well, >>>>> *anything*. The sort of behaviour you are seeing is sometimes called >>>>> "action at a distance" -- something, anything, anywhere in your >>>>> program, possibly buried deep, deep down inside some function you >>>>> might never suspect, is changing the global variable. >>>> >>>> I think you are overstating your case. Classes and functions are >>>> variables too and in general nobody seems to have a problem with them >>>> being global. >>>> >>>> >>> It's global *variables* that are to be avoided. constants like clsases >>> and functions are fine. On the other hand, class attributes can be >>> variable, and thus are to be avoided when reasonable. >> >> Python has no constants. Classes and functions can be changed just like >> any other variable. I agree that classes and function are generally >> meant to be constant, but often enought so are global int variables. > > You are technically correct, but missing the point. If I wrote code that > went around reassigning names from one function to another function, I > would very likely soon work myself into a state of utter confusion: > > def func(x): > ... > > # later > save_func = func > func = lambda x, y: do_stuff(x, 3*y)-4 > result = something_that_calls_func() > func = save_func > > > Nasty, horrible code, yes? But it's nasty and horrible because "func" is > bound to a function, it would be equally nasty and horrible if it was a > data type (a string, a list, an int, a flag, ...) instead. > > Since classes and functions are First Class objects in Python, naturally > if you treat them as global *variables* rather than global *constants* > you can end up with problems. The problem is not the global part alone. > Global constants, or pseudo-constant-by-convention-only, are fine. I don't think there is a big disagreement on this, I just thought you overstated your case as you originally worded it. >> And some of those that do change, only do so in the initialisation phase >> and should be considered constant for the rest of the program. >> >> My point was that Steven has no way of knowing what exactly is going on >> here and so shouldn't be making such a sweeping statement. > > On the contrary, I can read the Original Poster's description of the > problem, and then use my ability to reason to deduce what the most likely > explanation was. > > Now of course I might be wrong. I don't claim infallibility or > omniscience. But I'm not an idiot, and if the OP says that a global > variable has one value at one time, and then some time later has a > different value, there are two likely possibilities: > > * The variable was changed by some other piece of code, i.e. it > actually was being used as a *global variable*. Sure. But was that because it was intended to be used as a variable or was the intention to use it as a constant but because of a bug it was changed anyway? I don't think you have enough information to discriminate between these two cases and for the possibility of this being the latter case I found your disgression into the harm of global variable too strongly worded. -- Antoon Pardon.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-08-19 09:32 +0100 |
| Message-ID | <mailman.17.1376901181.19984.python-list@python.org> |
| In reply to | #52630 |
On Mon, Aug 19, 2013 at 9:16 AM, Antoon Pardon <antoon.pardon@rece.vub.ac.be> wrote: > Op 19-08-13 09:45, Dave Angel schreef: >> Antoon Pardon wrote: >>> I think you are overstating your case. Classes and functions are >>> variables too and in general nobody seems to have a problem with them >>> being global. >>> >> >> It's global *variables* that are to be avoided. constants like clsases >> and functions are fine. On the other hand, class attributes can be >> variable, and thus are to be avoided when reasonable. > > Python has no constants. Classes and functions can be changed just like > any other variable. I agree that classes and function are generally > meant to be constant, but often enought so are global int variables. # telnet.py IAC = 0xFF GA = 0xF9 WILL = 0xFB WONT = 0xFC DO = 0xFD DONT = 0xFE # connection.py from telnet import IAC,DO,DONT To be sure, Python won't stop me from changing the value of DONT. But it's a constant, and its value is defined elsewhere (RFC 854). (In this instance, an enum would probably be the better option; but this is an example of a more general case.) In connection.py, I don't care that I've taken a "copy" of the integer 0xFE. It's never going to change; it is a constant in the best tradition of "named number". I could hard-code 0xFE everywhere and the code would work *just fine*, but it'd be less readable, so I don't. Python does have constants. It just doesn't have interpreter support for them. Same as private members, in fact. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-08-19 17:05 +0000 |
| Message-ID | <52125071$0$29986$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #52678 |
On Mon, 19 Aug 2013 09:32:53 +0100, Chris Angelico wrote: > Python does have constants. It just doesn't have interpreter support for > them. Same as private members, in fact. "Constant by convention". I wish Python had stronger support for enforcing constantness, to whit, some way to say "you can't rebind or delete this name once it is bound". You can do it with attributes, by use of property, or in C extensions, but you cannot do it with top-level name bindings. It makes me terribly sad that you can do this: import math math.pi = 3.0 although I can't decide whether I am less sad or more sad to see that the behaviour of math.sin and friends doesn't depend on math.pi. Now, of course, and I don't expect any such "constants" to be proof against a dedicated attacker. One can work around read-only properties, and I expect that any future "no-rebind" constants will also be capable of being worked around. This is Python, not Haskell or Ada. But, naming convention or no naming convention, it is still valuable to get an exception if you accidentally rebind something that you shouldn't rebind. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2013-08-19 22:34 +0200 |
| Message-ID | <mailman.40.1376944517.19984.python-list@python.org> |
| In reply to | #52695 |
Op 19-08-13 19:05, Steven D'Aprano schreef: > > I wish Python had stronger support for enforcing constantness, to whit, > some way to say "you can't rebind or delete this name once it is bound". > You can do it with attributes, by use of property, or in C extensions, > but you cannot do it with top-level name bindings. It makes me terribly > sad that you can do this: > > import math > math.pi = 3.0 > > > although I can't decide whether I am less sad or more sad to see that the > behaviour of math.sin and friends doesn't depend on math.pi. Why should you expect math.sin and friends be dependant on math.pi? AfAIR the numerical algorithms for calulating sin and friends don't depend on (the value of) pi. So there is no reason to suspect that altering math.pi would have any effect on the results of these functions. -- Antoon Pardon
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2013-08-20 05:48 +0000 |
| Message-ID | <52130335$0$29885$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #52705 |
On Mon, 19 Aug 2013 22:34:00 +0200, Antoon Pardon wrote: > Op 19-08-13 19:05, Steven D'Aprano schreef: > > >> I wish Python had stronger support for enforcing constantness, to whit, >> some way to say "you can't rebind or delete this name once it is >> bound". You can do it with attributes, by use of property, or in C >> extensions, but you cannot do it with top-level name bindings. It makes >> me terribly sad that you can do this: >> >> import math >> math.pi = 3.0 >> >> >> although I can't decide whether I am less sad or more sad to see that >> the behaviour of math.sin and friends doesn't depend on math.pi. > > Why should you expect math.sin and friends be dependant on math.pi? > AfAIR the numerical algorithms for calulating sin and friends don't > depend on (the value of) pi. So there is no reason to suspect that > altering math.pi would have any effect on the results of these > functions. Of course they depend on pi. Or rather, they depend on the geometric properties of circles, which are related to pi. If the ratio of the circumference of a circle to its diameter was exactly 3, instead of 3.1415..., then sine and cosine functions would be periodic with period 6 rather than τ = 2π. If you consider the implementation of sin and cos functions, they usually reduce the argument modulo π to something in the first quadrant, and then use symmetry to adjust the value. So changing the value of pi could, in principle, change the implementation of sin, cos and tan. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | wxjmfauth@gmail.com |
|---|---|
| Date | 2013-08-19 23:40 -0700 |
| Message-ID | <697cde04-0ec2-44d6-85b8-3e95bce3f7f4@googlegroups.com> |
| In reply to | #52715 |
Le mardi 20 août 2013 07:48:37 UTC+2, Steven D'Aprano a écrit : > On Mon, 19 Aug 2013 22:34:00 +0200, Antoon Pardon wrote: > > > > > Op 19-08-13 19:05, Steven D'Aprano schreef: > > > > > > > > >> I wish Python had stronger support for enforcing constantness, to whit, > > >> some way to say "you can't rebind or delete this name once it is > > >> bound". You can do it with attributes, by use of property, or in C > > >> extensions, but you cannot do it with top-level name bindings. It makes > > >> me terribly sad that you can do this: > > >> > > >> import math > > >> math.pi = 3.0 > > >> > > >> > > >> although I can't decide whether I am less sad or more sad to see that > > >> the behaviour of math.sin and friends doesn't depend on math.pi. > > > > > > Why should you expect math.sin and friends be dependant on math.pi? > > > AfAIR the numerical algorithms for calulating sin and friends don't > > > depend on (the value of) pi. So there is no reason to suspect that > > > altering math.pi would have any effect on the results of these > > > functions. > > > > > > Of course they depend on pi. Or rather, they depend on the geometric > > properties of circles, which are related to pi. If the ratio of the > > circumference of a circle to its diameter was exactly 3, instead of > > 3.1415..., then sine and cosine functions would be periodic with period 6 > > rather than τ = 2π. > > > > If you consider the implementation of sin and cos functions, they usually > > reduce the argument modulo π to something in the first quadrant, and then > > use symmetry to adjust the value. So changing the value of pi could, in > > principle, change the implementation of sin, cos and tan. > > > > > > -- > > Steven --------- Never heard about series, Taylor, Maclaurin, ... ? jmf
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2013-08-20 08:55 +0200 |
| Message-ID | <mailman.49.1376981719.19984.python-list@python.org> |
| In reply to | #52715 |
Op 20-08-13 07:48, Steven D'Aprano schreef: > On Mon, 19 Aug 2013 22:34:00 +0200, Antoon Pardon wrote: > >> Op 19-08-13 19:05, Steven D'Aprano schreef: >> >> >>> I wish Python had stronger support for enforcing constantness, to whit, >>> some way to say "you can't rebind or delete this name once it is >>> bound". You can do it with attributes, by use of property, or in C >>> extensions, but you cannot do it with top-level name bindings. It makes >>> me terribly sad that you can do this: >>> >>> import math >>> math.pi = 3.0 >>> >>> >>> although I can't decide whether I am less sad or more sad to see that >>> the behaviour of math.sin and friends doesn't depend on math.pi. >> >> Why should you expect math.sin and friends be dependant on math.pi? >> AfAIR the numerical algorithms for calulating sin and friends don't >> depend on (the value of) pi. So there is no reason to suspect that >> altering math.pi would have any effect on the results of these >> functions. > > > Of course they depend on pi. Or rather, they depend on the geometric > properties of circles, which are related to pi. If the ratio of the > circumference of a circle to its diameter was exactly 3, instead of > 3.1415..., then sine and cosine functions would be periodic with period 6 > rather than τ = 2π. Which is beside the point. The fact that nπ are the zeropoints of the sin function doesn't imply in any way that you somehow need to work with the value of π in order to calculate any result of the function. Just as the function x^2 - 2 has -√2 and √2 as zeropoints, yet when given a numerical value, you dont need (the value of) √2 in order to get the result. So setting a variable like sqrt2 to whatever value shouldn't lead us to suspect it would influence the zeropoints of that function. Likewise with π and the calculation of sin. > If you consider the implementation of sin and cos functions, they usually > reduce the argument modulo π to something in the first quadrant, and then > use symmetry to adjust the value. So changing the value of pi could, in > principle, change the implementation of sin, cos and tan. Yes there is this aspect, which is a fair point. -- Antoon Pardon
[toc] | [prev] | [next] | [standalone]
| From | wxjmfauth@gmail.com |
|---|---|
| Date | 2013-08-20 00:31 -0700 |
| Message-ID | <c5e3e122-06df-49d0-846d-365525cd6380@googlegroups.com> |
| In reply to | #52719 |
Le mardi 20 août 2013 08:55:18 UTC+2, Antoon Pardon a écrit : > > > > > > > > > If you consider the implementation of sin and cos functions, they usually > > > reduce the argument modulo π to something in the first quadrant, and then > > > use symmetry to adjust the value. So changing the value of pi could, in > > > principle, change the implementation of sin, cos and tan. > > > > Yes there is this aspect, which is a fair point. > > > > -- > > Antoon Pardon ----- Not really, see my previous post. This is only a geometric interpretation, useless for calculation. Consequence of an implementation: common trick to use and/or define pi: >>> const_pi = 4 * atan(1) >>> const_pi 3.141592653589793 jmf
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2013-08-20 09:55 +0200 |
| Message-ID | <mailman.51.1376985351.19984.python-list@python.org> |
| In reply to | #52722 |
Op 20-08-13 09:31, wxjmfauth@gmail.com schreef: > Le mardi 20 août 2013 08:55:18 UTC+2, Antoon Pardon a écrit : >> >>> >> > >> >> >> >>> If you consider the implementation of sin and cos functions, they usually >> >>> reduce the argument modulo π to something in the first quadrant, and then >> >>> use symmetry to adjust the value. So changing the value of pi could, in >> >>> principle, change the implementation of sin, cos and tan. >> >> >> >> Yes there is this aspect, which is a fair point. >> >> >> >> -- >> >> Antoon Pardon > > ----- > > Not really, see my previous post. This is only a geometric > interpretation, useless for calculation. No it is not. Steven is correct that if for example you want the value of sin(10), that in a typical implementation this will be reduced to calculating -sin(10 - 3π). This for two reasons. It is faster to first reduce the argument within the first kwadrant, do the series expansion and then correct for sign than to expand the series with the original argument and it is more acurate because first reducing asures that all terms will stay relatively small while using the original arguments can intrduce some large terms that will have to cancel each other but that will reduce acuracy. -- Antoon Pardon
[toc] | [prev] | [next] | [standalone]
| From | wxjmfauth@gmail.com |
|---|---|
| Date | 2013-08-20 02:15 -0700 |
| Message-ID | <3875e747-d33d-46ac-94ac-8f03ec5f9736@googlegroups.com> |
| In reply to | #52723 |
Le mardi 20 août 2013 09:55:44 UTC+2, Antoon Pardon a écrit : > Op 20-08-13 09:31, wxjmfauth@gmail.com schreef: > > > Le mardi 20 août 2013 08:55:18 UTC+2, Antoon Pardon a écrit : > > >> > > >>> > > >> > > > > > >> > > >> > > >> > > >>> If you consider the implementation of sin and cos functions, they usually > > >> > > >>> reduce the argument modulo π to something in the first quadrant, and then > > >> > > >>> use symmetry to adjust the value. So changing the value of pi could, in > > >> > > >>> principle, change the implementation of sin, cos and tan. > > >> > > >> > > >> > > >> Yes there is this aspect, which is a fair point. > > >> > > >> > > >> > > >> -- > > >> > > >> Antoon Pardon > > > > > > ----- > > > > > > Not really, see my previous post. This is only a geometric > > > interpretation, useless for calculation. > > > > No it is not. Steven is correct that if for example you > > want the value of sin(10), that in a typical implementation > > this will be reduced to calculating -sin(10 - 3π). > > > > This for two reasons. It is faster to first reduce the argument > > within the first kwadrant, do the series expansion and then > > correct for sign than to expand the series with the original > > argument and it is more acurate because first reducing asures > > that all terms will stay relatively small while using the > > original arguments can intrduce some large terms that will > > have to cancel each other but that will reduce acuracy. > > > > -- > > Antoon Pardon Ok. Fine. I was aware of the serie expansion, not about the reduction. jmf
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2013-08-19 11:03 +0200 |
| Message-ID | <mailman.19.1376903021.19984.python-list@python.org> |
| In reply to | #52630 |
Op 19-08-13 10:32, Chris Angelico schreef: > On Mon, Aug 19, 2013 at 9:16 AM, Antoon Pardon > <antoon.pardon@rece.vub.ac.be> wrote: >> Op 19-08-13 09:45, Dave Angel schreef: >>> Antoon Pardon wrote: >>>> I think you are overstating your case. Classes and functions are >>>> variables too and in general nobody seems to have a problem with them >>>> being global. >>>> >>> >>> It's global *variables* that are to be avoided. constants like clsases >>> and functions are fine. On the other hand, class attributes can be >>> variable, and thus are to be avoided when reasonable. >> >> Python has no constants. Classes and functions can be changed just like >> any other variable. I agree that classes and function are generally >> meant to be constant, but often enought so are global int variables. > > # telnet.py > IAC = 0xFF > GA = 0xF9 > WILL = 0xFB > WONT = 0xFC > DO = 0xFD > DONT = 0xFE > > > # connection.py > from telnet import IAC,DO,DONT > > > To be sure, Python won't stop me from changing the value of DONT. But > it's a constant, and its value is defined elsewhere (RFC 854). (In > this instance, an enum would probably be the better option; but this > is an example of a more general case.) This is irrelevant. That some context defines a constant, and that you can use a variable with the same name as a constant in python, doesn't contradict the statement that python (as a language) doesn't has constants. There is nothing in the language that would prevent buggy code from changing any of those variables. So from a python point of views these are just global variables. Just as the struct_global.y was in the original contribution. -- Antoon Pardon
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-08-19 10:18 +0100 |
| Message-ID | <mailman.20.1376903935.19984.python-list@python.org> |
| In reply to | #52630 |
On Mon, Aug 19, 2013 at 10:03 AM, Antoon Pardon <antoon.pardon@rece.vub.ac.be> wrote: > This is irrelevant. That some context defines a constant, and that you > can use a variable with the same name as a constant in python, doesn't > contradict the statement that python (as a language) doesn't has > constants. There is nothing in the language that would prevent buggy > code from changing any of those variables. So from a python point of > views these are just global variables. Just as the struct_global.y was > in the original contribution. And there's nothing preventing a program from using ctypes to overwrite an object's refcount, thus causing a segfault. So? The issue was regarding imports, and it's perfectly safe to import a constant, even if the interpreter doesn't protect you from then being a total idiot and changing it. ChrisA
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.python
csiph-web