In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
What is the anti-pattern in Python programming? I believe many inexperienced people don't know what to do about it. Therefore, this article summarizes the causes and solutions of the problem. Through this article, I hope you can solve this problem.
This article is a collection of irregular but occasionally subtle issues I have seen in code written by novice developers of Python. The purpose of this article is to help novice developers get through the stage of writing ugly Python code. To take care of the target audience, this article makes some simplifications (for example, ignoring the generator and the powerful iteration tool itertools when discussing iterators).
For novice developers, there are always some reasons to use anti-patterns, and I have tried to give them where possible. But often these anti-patterns make the code less readable, easier to bug, and not in line with the Python code style. If you are looking for more introduction materials, I highly recommend The Python Tutorial or Dive into Python.
Iteration
The use of range
Novice Python programmers like to use range to implement simple iterations, fetching every element of an iterator within the length of the iterator:
For i in range (len (alist)): print alist [I]
It should be kept in mind that range is not intended to implement simple iterations of a sequence. Compared to for loops defined by numbers, although for loops implemented in range are natural, they are easier to produce bug for sequence iterations, and are not as clear as constructing iterators directly:
For item in alist: print item
The abuse of range can easily lead to unexpected off-by-one errors, which is usually because novice programmers forget that the objects generated by range include the * parameters of range instead of the second, similar to substring in java and many other functions of this type. Novice programmers who think they don't go beyond the end of the sequence will create a bug:
# method of iterating the whole sequence error alist = ['her',' name', 'is',' rio'] for i in range (0, len (alist)-1): # Off by one! Print i, alist [I]
Common reasons for improper use of range:
1. Indexes need to be used in loops. This is not a reasonable reason to replace the use of indexes in the following ways:
For index, value in enumerate (alist): print index, value
two。 You need to iterate through two loops at the same time, using the same index to get two values. In this case, you can use zip to do this:
For word, number in zip (words, numbers): print word, number
3. Part of the iterative sequence is required. In this case, you only need to iterate sequence slices to achieve this, pay attention to add the necessary comments to indicate the intention:
For word in words [1:]: # does not include * element print word
There is one exception: when you iterate through a large sequence, the slicing operation is expensive. There is no problem if the sequence has only 10 elements, but if there are 10 million elements, or when slicing in a performance-sensitive inner loop, the cost becomes very important. In this case, consider using xrange instead of range [1].
In addition to iterating over sequences, an important use of range is when you really want to generate a sequence of numbers rather than to generate an index:
# Print foo (x) for 0 maxValue) {break;}} / / illegal here: there is no I processArray (y, I)
In Python, however, the same code always executes smoothly and gets the expected result:
For idx, value in enumerate (y): if value > max_value: break processList (y, idx)
This code will run normally, except if the child y is empty, the loop will never execute, and the call to the processList function will throw a NameError exception because idx is not defined. If you use the Pylint code review tool, you will be warned to use the variable idx that may not be defined.
The solution is always obvious. You can set idx to some special value before the loop, so you know what you will be looking for if the loop never executes. This mode is called Sentinel mode. So what value can be used as a sentinel? In the C era or earlier, when int dominated the programming world, the common pattern for functions that needed to return a desired error result was return-1. For example, when you want to return the index value of an element in the list:
Def find_item (item, alist): # None is more Python than-1 result =-1 for idx, other_item in enumerate (alist): if other_item = = item: result = idx break return result
In general, None is a better sentinel value in Python, even if it is not consistently used by the Python standard type (for example: str.find [2])
External scope
Novice Python programmers often like to put everything in the so-called external scope-- parts of python files that are not contained by code blocks (such as functions or classes). The external scope is equivalent to the global namespace; for the purposes of this section, you should assume that the contents of the global scope are accessible anywhere in a single Python file.
The external scope is very powerful for defining constants that are declared at the top of the file that the entire module needs to access. It is wise to use a distinctive name for any variable in the outer scope, for example, using the constant name IN_ALL_CAPS. This will not easily result in the following bug:
Import sys # See the bug in the function declaration? Def print_file (filenam): "Print every line of a file." With open (filename) as input_file: for line in input_file: print line.strip () if _ _ name__ = = "_ _ main__": filename = sys.argv [1] print_file (filename)
If you look closer, you will see that the definition of the print_file function uses filenam to name the parameter name, but the function body refers to filename. However, the program can still run well. Why? In the print_file function, when a local variable filename is not found, the next step is to find it in the global scope. Because the call to print_file is in the external scope (even with indentation), the filename declared here is visible to the print_file function.
So how to avoid such mistakes? First of all, do not set any value [3] without a global variable such as IN_ALL_CAPS in the external scope. Parameter parsing * * is given to the main function, so any internal variables in the function do not survive in the external scope.
This also reminds people to pay attention to the global keyword global. If you just read the value of the global variable, you don't need the global keyword global. You need to use the global keyword only if you want to change the object referenced by the global variable name. You can get more information about this discussion of the global keyword on Stack Overflow here.
Code style
Salute to PEP8
PEP 8 is a general style guide for Python code, and you should keep it in mind and follow it as much as possible, although some people have good reasons to disagree with some of these small styles, such as indented spaces or using blank lines. If you don't follow PEP8, you should have a better reason than "I just don't like that style." The following style guidelines are taken from PEP8 and seem to be something programmers often need to keep in mind.
Test whether it is empty or not
If you want to check whether a container type (for example, list, dictionary, collection) is empty, simply test it instead of using methods like checking len (x) > 0:
Numbers = [- 1,-2,-3] # This will be empty positive_numbers = [num for num in numbers if num > 0] if positive_numbers: # Do something awesome
If you want to save the result of whether positive_numbers is empty elsewhere, you can use bool (positive_number) as the result; bool is used to determine the true value of the if conditional statement.
Test whether it is None
As mentioned earlier, None can be used as a good sentinel value. So how do you check it?
If you explicitly want to test None, not just some other item with a value of False (such as an empty container or 0), you can use:
If x is not None: # Do something with x
If you use None as a sentinel, this is also the pattern expected by the Python style, for example, when you want to distinguish between None and 0.
If you just test whether the variables are useful values, a simple if pattern is usually sufficient:
If x: # Do something with x
For example, if you expect x to be a container type, but x may change to None as the return value of another function, you should consider this situation immediately. You need to pay attention to whether you have changed the value passed to x, otherwise you may think that True or 0. 0 is a useful value, but the program doesn't execute the way you want it to.
Translator's note:
[1] in Python2.x, range generates list objects and xrange generates range objects; Python 3.x abolishes the unified range object generated by xrange,range, and list can be generated explicitly with list factory functions
[2] string.find (str) returns the index value that str starts in string, or-1 if it does not exist
[3] do not set any value to the local variable name in the function in order to prevent the error when calling the local variable inside the function and call the variable with the same name in the external scope.
After reading the above, have you mastered the method of anti-pattern in Python programming? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.