On 5/24/21 11:33 AM, Cameron Simpson wrote:
On 24May2021 08:21, hw <h...@adminart.net> wrote:
On 5/24/21 12:03 AM, Cameron Simpson wrote:
On 23May2021 21:02, Stestagg <stest...@gmail.com> wrote:
On Sun, 23 May 2021 at 20:37, hw <h...@adminart.net> wrote:
I don't know about shadowing.

Shadowing is effectively saying “within this bit of code, (scope) I’m going
to use an already-used name for my own value”

An example might make this clearer:

     x = 1 # global variable

     def f(a):
         x = a * 2
         return x

Inside the function f() the name 'x" shadows the global "x"; references
to "x" are to the function's local vairable. Which is very desireable.

If it works that way, I would consider it an entirely different
variable.  Is there a way to access the global x from within a
function without transferring it through parameters of the function?
Than can also sometimes be useful.

Sure. You can declare a name like this:

     def f(a):
         global x  # find x in the global namespace (the module)
         x = a * 2
         return x

This is pretty rare and usually discouraged. Of there are times when it
is useful.

Note that in this function:

     x = 1
     y = 2

     def f(a):
         x = 3
         print(x, y)

"x" is local, because the function contains an assignment to it. "y"
comes from an outer scope (in this case, the global scope) because
there's no assignment to it.

Thanks!  That basically works the same as in perl then.

As Stestagg has mentioned, there are also tools called linters which
warn you about issues like this. Tools like pyflakes, pylint,
pycodestyle all inspect your code for a wide variety of potential errors
and discouraged habits.  Not to mention tools like mypy which do type
validation.

So you're saying one can't really go without those unless you want to
take the risk?

Self restraint and developing good habits does 99% of the work. Linters
are great for catching various accidents.

I never needed one before.

[...]
I'm not saying it shouldn't be allowed to defeat or to re-define stuff,
only that it shouldn't go through quietly.

Well, most of us use linters to exhibit that noise, rather than
requiring the code to be littered with special directives.

I usually code without much linter fuss until I've got the latest batch
of work (eg feature or fix) ready, commit the changes, then lint
vigorously and commit that polish before merging with the main line of
code.

Maybe python requires a different approach than other languages in that it doesn't allow for the overhead that can be used to make things easy to read and without guessing in other languages. That overhead can be a disadvantage, yet getting to used to not having it could take a while.

Finally, consider this code:

     num = input("Enter a number: ")
     num = int(num)

input() returns a string, which would need converting to a number before
some numeric stuff. Plenty of people write the above. To my mind, this
is also a kind of shadowing, and I like this instead:

     num_s = input("Enter a number: ")
     num = int(num_s)

where the "_s" indicates quietly that this variable holds a string.

Isn't that a kind of overhead python is trying to avoid?

Is that shadowing to your mind? Or not? If yes, should the language emit
noise there, too? Remembering that Python _values_ are strongly typed,
though the variables are not (a variable might reference any kind of
object, as above).

No, I don't see any shadowing in either example. In the first one, you (seem to) make sure that you get an integer (not considering what happens when the input is not something that can be cast into an integer) using the same variable by altering its contents.

In the second example, you're using two different variables, trying to cast the first one to an integer while assigning it to a second one which is implicitly declared.

If anything, I could argue that this is convoluted code because you're doing lots of stuff implicitly --- and that could be argued for both examples. You could make it worse like

  if(int(num = input("foo: ")) == 5):
    pass

involving side effects, but I don't know if python would allow you to do that. (Not that I would want to do something like this, but it would make sense to me if it could be done ...)

I wouldn't say that your opinion would be wrong regardless of what side
of this question you come down on, but Python's chosen a side: noise for
nonsensical things, but not noise for dubious things. But plenty of
linters to complain about dubious things.

What does python actually do in the first example? Does it overshadow a variable or does it change one? If it overshadows a variable, it would be dubious, if it doesn't, it won't be dubious.

There are more alternatives: Python might create a new variable with the same name and forget about the old one. Or it doesn't forget about the old one and the old one becomes inaccessible (unless you have a reference to it, if there is such a thing in python). How do you call that?
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to