The Python language is simple and easy to use, but it can cause subtle, difficult-to-catch errors that can easily fall into the trap for beginners.

So, here are some simple mistakes you can make to make Python easy to learn.

1, indent, symbols and Spaces are not correct

When writing code, people use indentation, alignment, and whitespace to improve the readability of the code.

But in Python, many features rely on indentation.

For example, when you create a new class, everything in that class is indented under the declaration, as is the case with decisions, loops, and other structural statements.

If you find problems with code execution, check to see if you’re using the correct indentation.

Take a look at the following example. Make sure to use correct and appropriate colons and indentation when using IF statements, as they can lead to syntax and indentation errors.



In the code above, there are two errors: missing; The next line is not indented correctly, and the code is executed incorrectly.



When you correct two problems in the above code, you will find that the whole code works fine.

Incorrect use of class variables



Here the output value is 1, and then we try to change the values of A.x and B.x to see what happens.



We only changed A.X. Why did C.x change?

Here’s a quick look at Python namespaces.

In Python, namespaces are a combination of name-to-object mappings. Names in different namespaces are not associated. The implementation of such mappings is somewhat similar to dictionaries in Python.

When you access an object’s properties by name, you first look in the object’s namespace. If the property is found, the value of the property is returned; If not, it looks in the class’s namespace, returns the value of the attribute if found, and throws an exception if not found.

In Python, class variables are handled internally as dictionaries and follow a method commonly called method resolution order (MRO).

MRO: Method Resolution Order (MRO) : Method Resolution Order (MRO) : Method Resolution Order (MRO) : Method Resolution Order (MRO), Python supports multiple inheritance.

So in the code above, since X cannot find the property C in the object’s namespace, it will look for it in the class. In other words, C has no x property of its own, independent of A. Thus, a reference to C.x actually refers to A.x.

Misunderstanding Python scope rules

It’s easy to make mistakes if you don’t understand Python’s scope rules, because Python uses a unique scope rule to determine the scope of variables.

Python range resolution is based on LEGB rules. Here is an overview of python range rules:

·L – stands for Local. It contains the (identifier/variable) name specified within the function (using def or lambda), instead of being declared using the global keyword.

·E – stands for Enclosing function locals. It contains names from the local scope of any/all enclosing functions (for example, using def or lambda).

·G – for global entity. It includes names that run at the top level of the module file or are defined using the global keyword.

·B – Refers to built-in plug-ins. It spans names that are pre-specified as built-in names, such as print, enter, open, and so on.

The LEGB rule specifies the following order for namespaces to search for names:

Local – > Enclosed – > Global – > Built-in

Consider the following example:



The above error occurs because when assigning a value to a variable in scope, Python automatically treats that variable as a local variable in that scope and hides any similarly named variables in the outer scope.

As a result, many people are confused when the code prompts an error and says you need to add an assignment statement to a function.

Consider an example encountered when using lists:





Why is foo2 wrong but foo1 is fine?

In this example, foo1 () does an assignment to LST, while foo2 () LST += [5] is simply short for LST = LST + [5]. We want to assign a value to LST, but the assigned value LST is based on LST itself, but it is not defined yet.

4. Python closure variable bindings

The python closure variable issue is also a point of confusion for beginners. Take a look at the following example:



Why is it 88888, not 02468, as I thought?

This is due to Python’s late binding mechanism, where the value of an internal function in a closure is queried only when it is called.

So when the lambda function returned by create_multipliers is called, the value of variable I is queried in a nearby scope. After create_multipliers generates the return array, the integer I is 4 and does not change, so each anonymous function in the return array is actually: Lambda x: 4 * x. ,

The solution is to keep the temporary values in the scope of the anonymous function as well, and query the value of the variable when the anonymous function is declared.

With that in mind, let’s change the code, surprise!



Name conflicts with Python standard library module

Python has a large library of modules right out of the box. However, problems can arise if you encounter a name conflict between a module’s name and that of a module with the same name in the standard library that comes with Python.

For example, import another library, which will try to import the Python standard library version of the module, but because you have a module with the same name, another package will import your version instead of the Python standard library by mistake.

Therefore, care should be taken to avoid using the same names as in Python standard library modules, and it is easier to change module names in packages than to submit Python Enhancement Proposal (PEP) to request name changes.

== == == == == == == == ==

Python has many operators, such as is, =, ==. Many beginners will misunderstand the meaning and usage of these three operators, resulting in code errors.

Comparison between objects is used in Python. You can use == or is, but the comparison between objects is not the same.

· IS compares whether the ID values of two objects are equal, whether they point to the same memory address, == Compares whether the contents of two objects are equal, whether the values are equal;





As you can see in the above example, b and A have the same memory address. They refer to the same block of memory, so is and == are both True because direct assignments are references to assignments. If b and A point to different memory after creating a new object, then b is a is False and b==a is True.

· Small integer objects [-5,256] are placed in the cache for reuse within the scope of the global interpreter, for example:





As you can see in the above example, b and A have the same memory address. They refer to the same block of memory, so is and == are both True because direct assignments are references to assignments. If b and A point to different memory after creating a new object, then b is a is False and b==a is True.

· Small integer objects [-5,256] are placed in the cache for reuse within the scope of the global interpreter, for example:





Python caches only small integer objects (range [-5, 256]), not all integer objects. Note that this is only executed on the command line and is not the same when executed on Pycharm or saved as a file because the interpreter has been partially optimized.

= and == have different meanings:

= means to assign, to assign some value to some variable, say a=3, to assign the value 3 to A.

It checks for equality and returns True or False, such as 1

1. They are equal, so return true. 1==2, they are not equal, so return false.

Example:



7. Abuse __init__

The __init__ method is used as a constructor in Python and is automatically called when Python allocates memory to a new class object.

First, __init__ is not equivalent to a constructor in C#; the instance is already constructed at the time it is executed.



Execution code:



It can be understood as:



That is, __init__ initializes an instantiated object.

Second, subclasses do not override __init__. When instantiating a subclass, __init__ defined in the superclass is automatically called.



However, if __init__ is overridden, instantiating a subclass does not implicitly invoke __init__ defined in the superclass.



An AttributeError: ‘C’ object has noattribute ‘name’ error is reported, so if you override __init__, it is best to explicitly call __init__ of the superclass in order to use or extend the behavior in the superclass.