Skip to main content


Still learning #Python. Whizzing through the lessons thinking "this is too easy." Then, of course, I sit down to write my first "real" program, an ASCII maze generator, and have to keep looking up things I already "learned." I also need to learn the type hints better.

gist.github.com/Ovid/6f67ebb40…

Unknown parent

mastodon - Link to source
Curtis "Ovid" Poe (he/him)

That prints out:

{'maze': <class '__main__.Maze'>, 'return': <class 'str'>}

So I guess I'm doing it right?

(And thanks for the kind words!)

This entry was edited (1 year ago)
in reply to Curtis "Ovid" Poe (he/him)

Last time I looked at Python, the only way to get a local variable was to use string eval (which they spelled exec()). Do you know if that's still true?
in reply to Füsilier Breitlinger

@barubary
"Get a local variable"? Not sure what you mean.

All variables are local and available in the function that they are defined in.

Global variables require the keyword but are bad practice.

in reply to bmaxv

@bmaxv @mdione @phiofx
By "local variable" I mean something that does not leak into or "pollute" the surrounding scope(s). Something like:

... regular code here ...<br>... tmp variable is not visible here ...<br># local scope starts here<br>tmp = Widget()<br>if tmp.foo():<br>    tmp.bar()<br># local scope ends here<br>... regular code here ...<br>... tmp variable is not visible here ...<br>

This is trivial in languages that let you declare local variables or provide local scopes, but in Python you cannot declare local variables and there are no local scopes, only entire functions.

You can try to fake a local scope by using a function (like the "IIFE" idiom in JavaScript), but that only moves the problem:

def local_scope_0():<br>    tmp = Widget()<br>    if tmp.foo():<br>        tmp.bar()<br>local_scope_0()<br>

The local variable is safely contained, but functions must be named in Python (OK, there are anonymous functions, but their bodies are limited to simple expressions), so now it is the function name that leaks into the surrounding scope. You still have to worry about name clashes and choosing unique identifiers, but this time for functions.

The only workaround I know is string eval:

exec('''<br>    tmp = Widget()<br>    if tmp.foo():<br>        tmp.bar()<br>''') # syntax might be off; it's been a while<br>

This ensures that there are no name clashes. tmp is safely contained in the exec() and won't clash with any identifier in the surrounding scope.
in reply to Füsilier Breitlinger

@barubary @mdione @phiofx the answer I would give is that it's incorrect to worry about these things *in Python*.

You are meant to put things into different functions or different classes or different files or different modules if you have to.

If this is a concern for the problem you are solving, python is the wrong tool for your problem.

in reply to Füsilier Breitlinger

@barubary all variables are local unless you declare them as nonlocal or global. do you have examples of what exactly do you mean by this?
in reply to Curtis "Ovid" Poe (he/him)

hey that is solid, I cannot think of any improvement :blobcatokhand:. I think types are fine, you can always check them with mypy or with the support from the IDE/editor you use. If you want to jump to the next level you can create a poetry project and add some pytest to it.
in reply to Leandro Leites

@Lleites Poetry project? Never heard of that.

So far, the types are rather interesting. I have one type warning in create_maze() that I had to add a hint to ignore (can't figure out why it's wrong), but so far, it's pretty cool!

in reply to Curtis "Ovid" Poe (he/him)

Poetry is widely used as a Python project/dependency manager. Check the documentation that does a better job than me python-poetry.org/docs/