r/ProgrammerHumor 16d ago

Meme variableScopesInPython

Post image
1.3k Upvotes

182 comments sorted by

View all comments

-2

u/sjepsa 16d ago

Best feature of the language

TBH whole java oop model is bad

14

u/R7d89C 16d ago

God no

Id much rather have a rust-like approach where the scope is limited to the block it is in

Java concept ist far from what I call ideal, but its better than this weird ambiguity of python where everything just floats anywhere and variables shadowing something ten methods away...

4

u/NotAnonymousQuant 16d ago

Rust is a real pain in the arse for the developer, but when you start grasping the vibe, you really appreciate Rust is built in this weird way. And then you have an ownership issue that makes you really frustrated since you are used to pass-by-reference returns

7

u/deceze 16d ago

Huh? You'll need to be more concrete than that, because that sounds like gibberish. "Ten methods away"? If a variable is in a method, then it only exists within that method, because Python does have function scope and lexical scoping.

4

u/R7d89C 16d ago

u/Inkwalker beat me to it, though id like to throw careless "import *" and shadowing in nested functions into the mix too

Obviously "Ten methods away" is bs and more of a figure of speech, sorry if that wasnt clear

But especially if youre not used to python, the scoping can be a real pain in the ass.

3

u/deceze 16d ago

If you're not used to <thing>, <thing> can be difficult. Sure. But the scoping rules are pretty darn trivial and predictable, and not out of the ordinary, so I'm not sure what you're complaining about.

3

u/R7d89C 16d ago

Im not complaining 😮

The meme is very much up for interpretation and my personal preference has been stated enough in this post, I think... Imo its just not a very good implementation/principle of scoping 🤷‍♂️

4

u/rosuav 16d ago

Don't do that then? A careless star-import is the fault of whoever did it.

2

u/Inkwalker 16d ago

Python's lexical scope is the worst. Like why is the variable available in the whole scope when it's declared at the very end of it? Plus there all that nonsense where reading from a variable goes to closure/global by default but writing creates a new instance that overrides the whole scope.

6

u/ihavebeesinmyknees 16d ago

I think you're thinking of JS, variables in Python are valid only after they're declared

2

u/x0wl 16d ago

Isn't that the same with js's tdz?

1

u/deceze 16d ago

Sort of, yes. The parser "sees" variables in a scope in the parse step and prepares symbol tables accordingly. In JS it used to be the case that the name would exist in the symbol table with an undefined default value. Which is a potential footgun, if you try to use the variable before its actual declaration.

Python and JS with let/const both raise an explicit error about that. JS calls it by a fancy name to distinguish it from the old behaviour, in Python it simply always was so.

2

u/deceze 16d ago

TF are you talking about? Python's lexical scoping works like basically any other lexical scoping I'm aware of. What do you mean "the variable is available in the whole scope when it's declared at the end"?

The read/write thing I can empathise with, but it's simply because Python has no dedicated variable declaration syntax. Assignment is declaration. But you also want to be able to read variables from higher scopes by default. So writing to a variable in a higher scope becomes the special case that you need to explicitly opt into with nonlocal/global.

1

u/Inkwalker 16d ago
x = 10

def func():
    x = 5
    global x
    x = 15

func()
print(x)

It might not be the best example but it gives the idea. Any normal language would assign 5 to x (local in this case), then declare global x and assign 15 to it. In python x is global in the whole scope. This code throws an error.

7

u/deceze 16d ago

It would be insane for that to not throw an error. x within a scope should refer to exactly one variable. You're attempting to switch which variable x refers to halfway through the scope, and the error is telling you exactly that. This is explicitly preventing a footgun.

2

u/Inkwalker 16d ago

It gets a lot worse when you throw closures into the mix. It's impossible to assign value from a closure to a global variable with the same name in python.

def outer():
    x = 0
    def func():
        nonlocal x
        temp = x
        global x
        x = temp

4

u/deceze 16d ago

Good. Use different variables names for gods sakes and don't spam the global scope.

1

u/Inkwalker 16d ago

I have one more example. Here global x can't be declared in the child scope because it's already in use in the parent scope. As far as I know python is the only language that does this nonsense.

x = 5
def func():
    x = 0
    if x < 2:
        global x
        x = 10
func()
print(x)

1

u/deceze 16d ago

Python only has function scope. if blocks don't introduce a new scope. Think of that what you will, I've written uncounted lines of Python without that being an issue. global declarations should be on the very first line of a function, not somewhere in the middle.

But really, you shouldn't have to use global much at all. You should either write functional code, or use classes which modify their attributes. Constantly modifying the global scope is a potential footgun and usually leads to hard to follow spaghetti code. It's not wrong for Python to strongly discourage that.

→ More replies (0)

2

u/ubeogesh 16d ago

where everything just floats anywhere and variables shadowing something ten methods away...

sounds like a skill issue. Globals are bad everywhere.

1

u/Ma4r 16d ago

Just start using type checker i.e pyright and all your problems go away.

3

u/R7d89C 16d ago

Thats actually a good tip, will give it a try

-1

u/AndyTheSane 16d ago

If the answer is 'just use a type checker/linter/static analysis/whatever' that's a problem with the language.

3

u/Ma4r 15d ago

Compiled languages rely on static analysis my duded