Examples of such constructions are considered + some obvious, but no less dangerous constructions that should be avoided in the code. The article is designed for python programmers with experience 0 - 1.5 years. Experienced developers can criticize or add with their own examples.
1. Lambda.
The pw variable in lambda is a reference to a variable, not to a value. By the time the function is called, the pw variable is 5
Problem code
to_pow = {} for pw in xrange(5): to_pow[pw] = lambda x: x ** pw print to_pow[2](10)
| Solution: Pass all variables explicitly in lambda
to_pow = {} for pw in xrange(5): to_pow[pw] = lambda x, pw=pw: x ** pw print to_pow[2](10)
|
2. An excellent order of searching for attributes with rhomboidal inheritance in the classes of the classical and the new style

| class A(): def field(self): return 'a' class B(A): pass class C(A): def field(self): return 'c' class Entity(B, C): pass print Entity().field()
| class A(): def field(self): return 'a' class B(A): pass class C(A, object):
|
3. Editable objects as default values
Magic:
def get_data(val=[]): val.append(1) return val print get_data()
| Decision:
def get_data(val=None): val = val or [] val.append(1) return val print get_data()
|
val = val or [] looks shorter and quite acceptable, but if 0, the empty string, False, etc. are not passed at the input to the function. Then you need to do the verification is None, as described in the google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Default_Argument_Values#Default_Argument_Values gogle-style
')
(Who has not read this document - I advise you to look in.)
4. Default values are initialized once.
import random def get_random_id(rand_id=random.randint(1, 100)): return rand_id print get_random_id()
5. Not taken into account the hierarchy of exceptions. If you do not keep in mind such lists
docs.python.org/2/library/exceptions.html#exception-hierarchy + exception lists of built-in modules + the exception hierarchy of your application, and do not use PyLint. Then you can write the following:
KeyError will never work
try: d = {} d['xxx'] except LookupError: print '1' except KeyError: print '2'
6. Interpreter caching of short strings and numbers
str1 = 'x' * 100 str2 = 'x' * 100 print str1 is str2
7. Implicit concatenation.
The missing comma does not generate exceptions, but results in the merging of adjacent strings. Such a situation can occur when, after the last element in the tuple, an optional comma is not put, and then the lines in the tuple are regrouped, sorted
tpl = ( '1_3_dfsf_sdfsf', '3_11_sdfd_jfg', '7_17_1dsd12asf sa321fs afsfffsdfs' '11_19_dfgdfg211123sdg sdgsdgf dsfg', '13_7_dsfgs dgfdsgdg', '24_12_dasdsfgs dgfdsgdg', )
8. The nature of the Boolean type.
True and False are the real 1 and 0, for which they invented a special name for the greater expressiveness of the language.
try: print True + 10 / False * 3 except Exception as e: print e
>>> type(True).__mro__ (<type 'bool'>, <type 'int'>, <type 'object'>)
docs.python.org/release/2.3.5/whatsnew/section-bool.htmlPython's Booleans were added with the goal of making code clearer.
To sum up the numbers 1 and 0, the sum of the str () and the repr () return the strings 'True' and 'False' instead of 1 'and' 0 '.
eight*. Outdated design. It is dangerous that the loss of a slash, or the transfer of only the first part of the expression does not lead to obvious errors. As a solution, use parentheses.
x = 1 + 2 + 3 \ + 4
ps: point number 8 * due to the fact that initially the article was mistakenly present two 7th points. So as not to knock down the numbering (since it already has links in comments) had to introduce such a designation.
9. Comparison operators and, or, unlike, for example, PHP do not return True or False, but return one of the comparison elements; in this example, the first positive element will be assigned to current_lang
current_lang = from_GET or from_Session or from_DB or DEFAULT_LANG
Such an expression as an alternative to the ternary operator will also work, but you should pay attention that if the first element of the list is '', 0, False, None, then the last element in the comparison will be returned, but the first element of the list will not be returned.
a = ['one', 'two', 'three'] print a and a[0] or None
10. To catch all exceptions and not to process them in any way. In this example, nothing unusual happens, but this design is fraught with danger and is very popular among beginners. You don’t need to write this way, even if you are 100% sure that the exception can not be processed in any way, as it does not guarantee that another developer will not add a line to the try-except block, an exception from which I would like to fix. Solution: write to the log, specify the type of exceptions that are intercepted, frame only the minimum necessary piece of code in try-except.
try:
11. Override objects from built-in. In this case, the objects list, id, type are redefined. Using the classic id, type in the function and the class list in the module in the usual way will not work. As a solution, install PyLint in your IDE and see what it says.
def list(id=DEFAULT_ID, type=TYPES.ANY_TYPE): """ W0622 Redefining built-in "id" [pylint] """ return Item.objects.filter(id=id, item_type=type)
If you can’t rewrite the code, you’ll need to access the built-in functions like this:
def list(id=None): print(__builtins__.id(list))
12. Working code, without surprises ... for you ... But another developer using mod2.py would be very surprised to notice that one of the attributes of the module suddenly changed. As a solution, try to avoid such actions, or at least introduce a function in mod2.py to override an attribute. Then studying mod2.py it will be possible even to understand that one of the attributes of the module can change.
UPD: Useful link on
lega :
Hidden features of PythonPS: Criticism, comments, additions are welcome.