In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
Python trap and defect list example analysis, in view of this problem, this article introduces the corresponding analysis and solution in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible method.
My personal definition of trap is this: the code seems to work, but not in the way you "take it for granted". If a piece of code goes wrong directly and throws an exception, I don't think it's a trap. For example, Python programmers should have encountered the "UnboundLocalError", example:
> axi1 > def func ():... A few days ago. Print a... > > func () Traceback (most recent call last): File "", line 1, in File "", line 2, in func UnboundLocalError: local variable 'a'referenced before assignment
For "UnboundLocalError", there are more advanced versions:
Import random def func (ok): if ok: a = random.random () else: import random a = random.randint (1,10) return a func (True) # UnboundLocalError: local variable 'random' referenced before assignment
Perhaps for many python newcomers, this Error is confusing. But I don't think this is a trap, because this code is bound to report an error, rather than running in the wrong way silently. Not afraid of real villains, afraid of hypocrites. I think defects are like hypocrites.
So which of the Python is really a trap?
*: use mutable object as the default parameter
This estimate is the best known. Python, like many other languages, provides default parameters, which are really a good thing, allowing function callers to ignore details (such as GUI programming, Tkinter,QT) and useful for lambda expressions. But if you use a mutable object as the default parameter, things are not so pleasant.
> def f (lst = []): Lst.append (1)... Return lst. > f () [1] > > f () [1,1]
Surprise or no surprise?! The reason is that everything in python is an object, the function is not listed, and the default parameter is just an attribute of the function. The default parameters are evaluated when the function is defined.
Default parameter values are evaluated when the function definition is executed.
There is a more appropriate example on stackoverflow to show that default parameters are evaluated when defined, rather than when called.
> import time > > def report (when=time.time ()):... Return when. > report () 1500113234.487932 > report () 1500113234.487932
Python docoment offers a standard solution:
A way around this is to use None as the default, and explicitly test for it in the body of the function > > def report (when=None):... If when is None:... When = time.time ()... Return when. > report () 1500113446.746997 > report () 1500113448.552873
Second: X + = y vs x = x + y
In general, the two are equivalent, or at least appear to be equivalent (this is also the definition of a trap-both look OK, but not necessarily correct).
> print x + = 1% print x 2 > x scene 1 + = 1% print x 2 > x = [1]; x = [2]; print x [1,2] > > x = [1]
Uh, hit in the face by the speed of light?
> x = [1]; print id (x); xx + [2]; print id (x) 4357132800 4357132728 > x = [1]; print id (x); x = [2]; print id (x) 4357132800 4357132800
The former x points to a new object, the latter x is modified in the original object, of course, that effect is correct depending on the application scene. At least, you know, sometimes the two are not the same.
Third, magical parentheses-()
Parentheses (parenthese) are widely used in various programming languages. In python, parentheses can also represent the data type of tuple, which is a sequence of immutable.
> a = (1,2) > type (a) > type (())
But what if there's only one element?
> a = (1) > type (a)
Magic is not magical. If you want to represent a tuple with only one element, the correct pose is:
> a = (1,) > type (a)
Fourth: generate a list where the element is a list
This is a bit like a two-dimensional array, of course, it is possible to generate a list of elements that are dictionaries, or, more generally, a sequence of elements that are mutable objects.
It's very simple:
> a = [[]] * 10 > > a [[], []] > > a [0] .append (10) > a [0] [10]
It looks good. It's simple, but.
> > a [1] [10] > > a [[10], [10], [10], [10], [10], [10], [10], [10]]
I guess this is not the result you expected. The reason is that list in python is a mutable object, and the above words all point to the same mutable object, the correct posture.
> a = [[] for _ in xrange (10)] > > a [0] .append (10) > a [[10], []]
Fifth, when accessing the list, modify the list
Lists (list) are widely used in python, and of course some elements are often added or deleted when accessing the list. For example, the following function attempts to delete an element in the list that is a multiple of 3:
Def modify_lst (lst):... For idx, elem in enumerate (lst):... If elem% 3 = 0:... Del lst [idx]
Test it,
> lst = [1, 2, 3, 4, 5, 6] > modify_lst (lst) > lst [1, 4, 5]
There seems to be nothing wrong with it, but it's just luck.
> lst = [1, 2, 3, 6, 5, 4] > modify_lst (lst) > lst [1, 2, 6, 5, 4]
In the above example, the element 6 has not been deleted. If you print idx in the modify_lst function, item can see that lst is getting shorter, but idx is increasing, so in the error example above, when 3 is deleted, 6 becomes the second element of lst (starting with 0). In C++, you have the same problem if you use an iterator to delete elements while traversing the container.
If the logic is simple, it is a good idea to use list comprehension
Sixth, closures and lambda
This is also an example of old growth talk, and there is a similar situation in other languages. Let's first look at an example:
> def create_multipliers (): Return [lambda x:i*x for i in range (5)]... > for multiplier in create_multipliers ():... Print multiplier (2)...
The return value of the create_multipliers function is a list, and each element of the list is a function-- a function that multiplies the input parameter x by a multiple I. The expected result is 0pm 2pm 4pm 6pm 8. But the result is five 8s, the accident is not unexpected.
Because lambda is often used when this trap occurs, it may be thought that it is a problem with lambda, but lambda says it is unwilling to take the pan. The essence of the problem lies in the attribute lookup rule in python, LEGB (local,enclousing,global,bulitin). In the above example, I is in the scope of the closure (enclousing), while the closure of Python is late binding, which means that the value of the variable used in the closure is queried when the internal function is called.
The solution is also simple, which is to change the closure scope to a local scope.
> def create_multipliers (): Return [lambda x, I = i:i*x for i in range (5)]...
Seventh, define _ _ del__
Most computer majors may have learned C and C codes first, and they should be very familiar with the concepts of construction and destructors. So, when you switch to python, you naturally want to know if there is a corresponding function. For example, RAII, which is well known in C++, manages the declaration cycle of resources (such as memory, file descriptors) through construction and destructions. What do you do to achieve the same effect in python, that is, you need to find a function that must be called when the object is destroyed, so you found the _ _ init__, _ _ del__ function. You may simply write two examples to find that it really works. But in fact, it may have fallen into a trap, which is described in python documnet:
Circular references which are garbage are detected when the option cycle detector is enabled (it's on by default), but can only be cleaned up if there are no Python-level _ del__ () methods involved.
To put it simply, if the object in the circular reference defines _ _ del__, then python gc cannot be recycled, so there is a risk of memory leakage
Eighth, different postures import the same module
The example modifies the stackoverflow example slightly, assuming that there is now a package called mypackage, which contains three python files: mymodule.py, main.py, and _ _ init__.py. The mymodule.py code is as follows:
L = [] class A (object): pass
The main.py code is as follows:
Def add (x): from mypackage import mymodule mymodule.l.append (x) print "updated list", mymodule.l, id (mymodule) def get (): import mymodule print 'module in get', id (mymodule) return mymodule.l if _ _ name__ =' _ main__': import sys sys.path.append ('.. /') add (1) ret = get () print "lets check", ret
Run python main.py and the result is as follows:
Updated list [1] 4406700752 module in get 4406700920 lets check []
As you can see from the running results, the mymodule of import is not the same module,ID in the add and get functions. Of course, in python2.7.10, line 13 of main.py is required to have this effect. You might ask, who would write such a code on line 13? In fact, in many projects, for the convenience of import, a bunch of paths are added to sys.path. So in the project, it is very necessary for everyone to agree on an import approach.
Ninth, python upgrade
Python3.x is not backward compatible, so be careful when upgrading from 2.x to 3.x, here are two points:
In python2.7, the return value of range is a list; in python3.x, a range object is returned.
Map (), filter (), and dict.items () return lists in python2.7 and iterators in 3.x. Of course, most iterators are better choices, more pythonic, but they also have the drawback that they can only be traversed once. In the sharing of instagram, it is also mentioned that this leads to a deceptive bug.
Tenth, gil
Ends with GIL, because gil is a recognized flaw in Python!
Students from other languages may see that python uses the threading module and then uses it, only to find that the effect is not right, and then it will spray, what the heck.
There is no doubt that python is a very easy-to-use and powerful language. Python is very flexible and customizable. At the same time, there are some traps to find out that these traps can be better mastered and used in this language.
The answers to the sample analysis questions about Python traps and defect lists are shared here. I hope the above content can be of some help to you. If you still have a lot of doubts to be solved, you can follow the industry information channel for more related knowledge.
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.