When defining a python function, I find it hard to debug if I had a typo in a variable name and that variable already exists in the outer scope. I usually use similar names for variables of the same type of data structure, so if that happens, the function still runs fine but just returns a wrong result. So is there a way to prevent python functions to read outer scope variables?
You're going against the point of having Scopes at all. We have local and global scopes for a reason. You can't prevent Python from seeing outer scope variables. Some other languages allow scope priority but Python's design principles enforce strong scoping. This was a language design choice and hence Python is the wrong language to try to prevent outer scope variable reading.
Just use better naming methodologies to ensure no confusion, you change up variable names by using the Find-Replace function that most text editors provide.
They say you should avoid usage of global variables if possible. Also, keep in mind, that python has rules on searching variables in the specific order.
So you can avoid checking global variables only if you will delete them, but it makes usage of global variables useless.
Related
In Python I have several functions that use the location of the user's directory as a way of determining where to put files.
I currently use a "global" variable for all the functions to use.
home = os.path.expanduser('~')
I'm wondering if this is good coding practice.
The upside of this is that the program only needs to execute this code only once.
I could also have each function call os.path.expanduser each time it is called.
Which is the more pythonic one? Or is there a pythonicer way?
There's nothing wrong with globals. It's a consequence of how you designed your program. You wrote a few functions and put them in a module, and globals are a way to share data between individual functions in a module.
For example, had you decided to go with an object oriented design, then one could argue that globals should be avoided and shared data should be encapsulated. But you didn't do that, so globals are fine.
It is ok to use global constants. At the end all the first-level function and classes defined in the same module are also "global" in this sense.
Using gobal variables becomes messy when different components of the system start re-assigning their values or mutate their content. In this case it's an obvious antipattern and can lead to a debugging hell.
I have to share around 10 variables between functions, which are contained in the same .py file. The variables will be modified in almost every function. I know that global variables are evil, but unfortunately for now I have to keep few of them as global, while the rest I have been able to change the implementation and to pass them as an argument.
One way of doing this would be using the "global" keyword, but I have run into another option, that would be placing them in an empty module, and importing the module every time.
I am just a beginner in python, what would be the best way to do this?
EDIT: This is a rewriting of a code based almost completely on global variables. Almost all the functions are now in a class, the variables are used with self.name_var. However, since we are using multiprocess with Array, few variables have to remain globals.
Thanks,
Andrea
Just do not do it, put all the functions, if they are related, in a class and make the variables accessible with self. Using a different module is worst.
When there is a long function, how to limit the scope of variables within only a section of the function? I know in many languages one can do this with {}. How to do this in python?
I am aware that a separate function for just that section will encapsulate variables to its local namespace. But for a long, linear function, many people argue that it does not make sense to write many functions (and thus names) that are only called once.
Generally speaking, you can't. Python only creates scopes for modules (files, generally), classes, and functions; variables can have a more limited lifetime only in a few special cases, like the target_list in a list comprehension in Python 3. There's no block-level scope like in Perl.
So, your possible workarounds are:
Create single-use functions or classes. The function would have to be called, whereas the class would never have to be named again after its definition, because class definitions are executed immediately.
del variables when you're done with them.
Fun fact: coming to terms with this limitation of Python is what finally got us to get rid of let in Hy, because there's no way to make it work as one would expect. Update 5 years later: yet another version of let is implemented, and the way it works is by implementing our own entire system for tracking the scopes of variables, and enforcing it by issuing compile-time errors and adding nonlocal and global when needed. I guess there are no shortcuts here.
Do you have to write, for example, global var right before defining what var is or can you just kind of list all the global variables that you are going to use somewhere high up and then define them later on?
Generally accepted "best practice" - the quotes because it is often considered that global variables are not a good idea - is to have all your globals initialised near the top of the file, usually just after the imports, then to use the global statement in functions that change them.
The convention is to have all your globals ALL_UPPERCASE which makes a lot of sense as it does make it easier to spot when you are inadvertently masking them by assigning a local variable of the same name, (without the global statement).
Note that globals that are not intended to be accessed outside of the file should start with an underscore so that they are not imported by default.
It is also a reasonably good idea to always have any global statement(s) at the start of any functions that write to them - just after the docstring - for a similar reason.
To summarise - if you have to have them you can put them anywhere but you probably shouldn't for reasons of readability and maintainability.
In Python, you don't need to declare variables before using them. This includes globals.
If you are interested in sort of "reserving" the name early, you might want to assign them to None. Python is a highly dynamic language though, and your "reservations" could easily be clobbered by other code.
In Alex Martelli's response to Making a Python script Object-Oriented, he mentions that putting module level code into a function and then calling the function is faster in Python. Can someone explain why and whether it's true for all implementations of Python?
This is mostly due to variable look-up. Looking up a variable in the global scope requires a dictionary look-up. In contrast, the compiler determines local names statically and references them by index, so no dictionary look up is required.
Note that in Python 2.x the presence of an exec statement inside a function will deactivate this optimisation, since names can't be determined statically any more. In Python 3.x, exec() is a regular function, and as such it isn't allowed to change the variables in the local scope.