I am somewhat new to Python--beginner moving to intermediate--and would like to know how more experienced Python coders name their call and function variables.
Specifically, I like to name the call variables the same as the called function's 'receive' variables. Ditto the return variables.
Works fine, but are there problems I could run into, outside of changing a variable to global in the future?
An example call: v_Array = f_InitSpecified2DArray(v_Width,v_Length)
The example called or 'receiving' function: def f_InitSpecified2DArray(v_Width, v_Length):
And I do the same in the return as well: return v_Array
def f_InitSpecified2DArray(v_Width, v_Length):
v_Array = [v_Width, v_Length]
return v_Array
v_Array = f_InitSpecified2DArray(v_Width,v_Length)
The question is: Shall I expect any conflict resulting from reuse of name v_Array inside the function return and later in the calling code, where it goes assigned into variable with the same name v_Array?
Thanks.
No, this will not cause you difficulties, and doesn't cause confusion - for you, your readers, or the Python interpreter. Certainly it's less confusing than making up a new name just to differ from the parameter name, which is unnecessary. In fact, you'll often encounter the same name being used for both a named parameter and its argument, as in
runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
which comes from doctest.py in the standard library (for Python 3.3).
It's instructive to search the standard library for this pattern, <name>=<same_name> (abuse of notation which I'll rectify in a moment), as its occurrences are examples of just what you're asking about. On OS X and Linux, the following command will show all lines in the standard library (plus site-packages) with occurrences of the pattern:
grep -Er --include=*.py '(\b[[:alnum:]]+\b)=\1\b' /path/to/pythonlib
On a Mac, for example, /path/to/pythonlib for Python 3.3 is usually /Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3.
This command shows how many lines feature the construct, many of which have multiple occurrences:
grep -Er --include=*.py '(\b[[:alnum:]]+\b)=\1\b' /path/to/pythonlib | wc -l
I get a count of 1129, which includes a few dozen in my site-packages subdirectory. In other words, it's quite common.
Read PEP 008 titled "Style Guide for Python Code"
You seem to search for something more precise and systematic, this I appreciate, but you will safe a lot of effort and confusion to yourself and others dealing with your code, if you try to folow the PEP 008.
As usual, you will not find it followed everywhere, but that is life.
To your question about function names and variables - PEP 008 recommends using lowercase names with words separated by underscore.
local variable names are irrelevant, it really does not matter what variable name you use for return.
And do not plan moving variables into global scope too early, you shall in fact working in the other direction.
Related
The docs states that:
It is important to realize that scopes are determined textually: the global scope of a function defined in a module is that module’s namespace, no matter from where or by what alias the function is called. On the other hand, the actual search for names is done dynamically, at run time
I understand the first part: scopes are determined textually. But what does it mean that the actual search for names is done dynamically at run time? As opposed to what?
Let's try to compare this to what happens in C for instance, as I understand that this is the opposite of what happens in Python.
In C, consider the following code:
int a = 5
printf("The value of a is: %d\n", a);
So in C, the actual search for names is done at compile time - that means that the compiled machine code for the printf function will contain reference to the memory address of a whereas in Python
a = 5
print(a)
The compiled code of the print(a) will contain instructions for going looking in the namespace dictionary for what is pointed to by a and then access it.
Is that correct?
It means that a name can suddenly start resolving to something else, because it was redefined during the execution of the program. The alternative would be to resolve names when the program is read and parsed, and stick to this interpretation. (Which would be somewhat faster allow considerable additional optimization, e.g. by "knowing" things about the default behavior of Python built-in functions; but it is not how the language was designed.)
Here's an example that suddenly changes behavior:
for n in range(3):
print(max([10, 20, 30]))
max = min
This loop will print what you expect on the first iteration, but from then on the identifier max will refer to the local variable max, and will resolve to the builtin min(). Silly, but realistic use cases are a different question...
As opposed to being done statically at compile-time.
For instance in a language like C or Rust, by default symbols are looked up at compile-time, and at runtime the code just goes to whatever was resolved during compilation.
In Python however, every time you call a function the interpreter will look for that name in the relevant scope(s), then will use whatever's bound to that name at that point in time. Semantically if not necessarily technically.
So if e.g. you swap the object assigned to that name, then the code will call the remplacement instead of the original. Even if the replacement is not callable at all.
I'm new to Python. I'm writing some code in Sublime and it highlights the word 'input'
I use it as a variable name and it seems to work, so I wondered whether it may be a keyword in a newer version. (I'm currently using 2.7.5)
No, input is not a keyword. Instead, it is a built-in function.
And yes, you can create a variable with the name input. But please don't. Doing so is a bad practice because it overshadows the built-in (makes it unusable in the current scope).
If you must use the name input, the convention is to place an underscore after it:
input_ = input()
input is not a keyword, it's a function provided by the standard library and included in the builtins module (this module provides globally accessible variables and functions.):
>>> import builtins
>>> input is builtins.input
True
And sure, you can create a variable with the name input. It's perfectly fine for experienced and intermediate users to do so because they can easily figure that the input name has been re-used.
Use the best name for the content/intent you want to convey. If input is the best then use it (provided you don't need the builtin), and don't confuse readers with names like input_ (beginners will wonder whether there's a special meaning to a trailing underscore)
But if you're a beginner please don't re-define builtins, by overshadowing the built-in input (overshadowing a variable makes it unusable in the current scope) you'll end-up with this error when calling input() later on (in the same scope) and you may struggle to figure out why:
TypeError: 'str' object is not callable
Beginners should instead use another name, preferably not input_ because underscores have special meanings in python, as a result other beginners will wonder whether there's a special meaning for that trailing underscore (is it the same or related to leading underscores? or maybe to double underscores?)
In another comment someone stated that it is a bad practice to overshadow variables and he even came up with a convention that he borrowed from another use. After all, if overshadowing variables were a really bad practice, the python language designers wouldn't have allowed it in the first place, but they know and recognize that it has the potential to improve readability, just as it does in other languages. So they allowed it, and it also ease transition to Python from other languages where overshadowing is also allowed like C/C++, Java and even bash.
note: the conventional use for a trailing underscore is where it's impossible to use a name, like the keyword class in Python. Then you'd use class_ (but like I wrote above, it's best to avoid it in Python because underscores can confuse beginners as they can convey special meanings)
I often have the following code which either leads to variable shadowing or to a multiplication of local variables
def whenadult(age):
return 18 - age
age = 5
needtowait = whenadult(age)
age has the same logical role both when passed to the function as in the main code so I would like to avoid creating something like l_age in whenadult.
What is the pythonic way to solve the "shadowing vs. variable multiplication" dilemma?
UPDATE: following up on some comments I want to make it clear that I was looking for a Python best practice (as opposed to local vs. global variables scope)
The fact that the local variable (and function parameter) age happens to have the same name as a variable somewhere else in your program is irrelevant. The whole point of local variables is that they only live within the local scope of the function they're defined in.
The fact that the local variable has the same name as the variable used elsewhere as an argument is especially not a problem. In fact, it's very common in real-life code. For example, picking a random stdlib module, the 3.3 version of cmd, the Cmd.onecmd method has a variable named line, and it passes it as an argument to the self.default method, which binds it to a parameter that's also named line.
The fact that the variable used for the argument happens to be a global variable that you could have accessed, if you didn't have a local variable of the same name, is not a problem unless you actually wanted to access that global variable. Which you didn't want to in your existing code, and almost never should want to. In this case, and in most real-world cases, it's simply a coincidence that means nothing and affects nothing, not a problem you have to solve.
The problem you're having is that PyCharm can't guess whether you wanted the global age to be accessible in whenadult. Is it possible (if not in this trivial case, maybe in more complex cases) that a human might be similarly confused, slowing down his comprehension of your code? Or that you'll one day have to write code in some environment where your code reviewers or teacher or whatever will reject your code because it doesn't pass some linter with no warnings? Maybe.
But really, in any such environment, they'd probably complain about you using global variables in the first place. And you really don't need to here. The only reason age is a global is that it has to be accessible to the top-level code. If you move that code into a function, age can become a local in that function. For example:
def whenadult(age):
return 18 - age
def main():
age = 5
needtowait = whenadult(age)
main() # possibly with an if __name__ == '__main__' guard
This will make PyCharm happy, and any linter tools, and any easily-confused or rigidly-minded human readers. It'll even make your code a tiny bit faster. On the other hand, it's more code to read—only three lines and one indent, but then the whole program is only eight lines long. So, it's a tradeoff that you can make on a case-by-case basis.
Whenever I got the warning of shadowing variable in PyCharm. I would try to rename the local variable to use the underscore prefix as the convention. That's another way to consider in addition to wrap global variables into a main() function.
def whenadult(_age):
return 18 - _age
age = 5
needtowait = whenadult(age)
PyCharm is going out of its way to prevent you from accidentally accessing(usually due to typos) a variable from the outer scope because doing so can create really nasty bugs.
Short Answer:
Most executables don't need to access the global state, so follow this structure that makes main a python function:
def helper_function():
# a function that will be used by main()
.
.
.
def main():
# make MAIN a function.
helper_function()
if __name__ == '__main__':
main()
# DONT define any variables here in this GLOBAL scope
I've been thinking about this far too long and haven't gotten any idea, maybe some of you can help.
I have a folder of python scripts, all of which have the same surrounding body (literally, I generated it from a shell script), but have one chunk that's different than all of them. In other words:
Top piece of code (always the same)
Middle piece of code (changes from file to file)
Bottom piece of code (always the same)
And I realized today that this is a bad idea, for example, if I want to change something from the top or bottom sections, I need to write a shell script to do it. (Not that that's hard, it just seems like it's very bad code wise).
So what I want to do, is have one outer python script that is like this:
Top piece of code
Dynamic function that calls the middle piece of code (based on a parameter)
Bottom piece of code
And then every other python file in the folder can simply be the middle piece of code. However, normal module wouldn't work here (unless I'm mistaken), because I would get the code I need to execute from the arguement, which would be a string, and thus I wouldn't know which function to run until runtime.
So I thought up two more solutions:
I could write up a bunch of if statements, one to run each script based on a certain parameter. I rejected this, as it's even worse than the previous design.
I could use:
os.command(sys.argv[0] scriptName.py)
which would run the script, but calling python to call python doesn't seem very elegant to me.
So does anyone have any other ideas? Thank you.
If you know the name of the function as a string and the name of module as a string, then you can do
mod = __import__(module_name)
fn = getattr(mod, fn_name)
fn()
Another possible solution is to have each of your repetitive files import the functionality from the main file
from topAndBottom import top, bottom
top()
# do middle stuff
bottom()
In addition to the several answers already posted, consider the Template Method design pattern: make an abstract class such as
class Base(object):
def top(self): ...
def bottom(self): ...
def middle(self): raise NotImplementedError
def doit(self):
self.top()
self.middle()
self.bottom()
Every pluggable module then makes a class which inherits from this Base and must override middle with the relevant code.
Perhaps not warranted for this simple case (you do still have to import the right module in order to instantiate its class and call doit on it), but still worth keeping in mind (together with its many Pythonic variations, which I have amply explained in many tech talks now available on youtube) for cases where the number or complexity of "pluggable pieces" keeps growing -- Template Method (despite its horrid name;-) is a solid, well-proven and highly scalable pattern [[sometimes a tad too rigid, but that's exactly what I address in those many tech talks -- and that problem doesn't apply to this specific use case]].
However, normal module wouldn't work here (unless I'm mistaken), because I would get the code I need to execute from the arguement, which would be a string, and thus I wouldn't know which function to run until runtime.
It will work just fine - use __import__ builtin or, if you have very complex layout, imp module to import your script. And then you can get the function by module.__dict__[funcname] for example.
Importing a module (as explained in other answers) is definitely the cleaner way to do this, but if for some reason that doesn't work, as long as you're not doing anything too weird you can use exec. It basically runs the content of another file as if it were included in the current file at the point where exec is called. It's the closest thing Python has to a source statement of the kind included in many shells. As a bare minimum, something like this should work:
exec(open(filename).read(None))
How about this?
function do_thing_one():
pass
function do_thing_two():
pass
dispatch = { "one" : do_thing_one,
"two" : do_thing_two,
}
# do something to get your string from the command line (optparse, argv, whatever)
# and put it in variable "mystring"
# do top thing
f = dispatch[mystring]
f()
# do bottom thing
In python, there is no way to differentiate between arguments, local variables, and global variables. The easy way to do so might be have some coding convention such as
Global variables start with _ and capital letter
arguments end with with _
_Gvariable = 10
def hello(x_, y_):
z = x_ + y_
Is this a Pythonian way to go? I mean, is there well established/agreed coding-standards to differentiate them in python?
=== ADDED ===
I just want to discriminate between arguments and local variables. As arguments are given from outside, and more like a ROM in the sense that it is not assumed to be read only.
C++ provides the const keyword to prevent the arguments from changing, but not for python. I thought appending _ can be one of a way to mimic this feature in python.
I would do all your python programming according to PEP 8 guidelines. Anyone who has to read your code will thank you for it.
http://www.python.org/dev/peps/pep-0008/
Why is there a need to distinguish between arguments and local variables, since one is merely a subset of the other. You can use locals(), globals(), and vars() to view scope if you are having local-global issues. The inspect module can help with that, too. And if possible, avoid using global variables as much as possible.
It is usually obvious in python which variables are local and which are global, since to modify a global variable you have to declare it using the the global keyword at the start of a function. However I sometimes add a global declaration even if it is not necessary for python to compile it, in order to emphasize that an object is global - e.g. modifying a mutable global data-structure.
Arguments should be obvious because they are in the function declaration.
As others have said constants should be in UPPER_CASE_WITH_UNDERSCORES, which is a convention shared by many languages.
If you find that you are having trouble keeping track of which are global, local and parameter variables I suggest that the problem may be your functions are too long and doing too much. Functions & methods should be short and do exactly one thing. I start to get the refactoring itch if my functions go over about 10-20 lines of code.
I recommend reading the book Clean Code by Robert Martin. The examples are in Java, but the principles apply to all languages.
That's absolutly awful. There is no reason whatsoever to use a special naming scheme for global and local objects. Also you should avoid having global objects unless they are functions, classes or constants.
Names for constants should be uppercase and seperated with underscores LIKE_THIS, class names look LikeThis and functions and method names should look like any other name. Names for objects which are implementation specific, can be changed/removed at any time or can not be relied on for any other good reasons should be prefixed with an underscore.
You should also read the Python styleguide PEP 8 which covers these and more style-related rules you should follow as long as it doesn't make your code less readable. Most Python projects follow this or at least a compatible version of this style guide.
Local variables are variables that are declared inside a function.
Global variables are variables that are declared outside a function.
For Example:
global_var = 5 #Global Variable
def add(a,b):
local_var = a+b #Local Variable
print("The sum is",local_var)
print("The global variable is",global_var)
add(10,20)