Python objects and name bindings

zhaozj2021-02-16  55

i = 1

This is a simple assignment statement, even if you start learning programming, you can find out its meaning - "Set the value of the variable i is 1".

i = 2

"Creating the value of the variable i is 2", when you see the following line code, you will definitely appear such a thought immediately.

Is this a problem? This simple-orderly assignment statement actually contains three important concepts in Python: name, binding, and objects. Python makes its own definitions for assignment statements: "The values ​​statement is used to bind (or rebound) to an object of an object, and it can also be used to modify the properties of variable objects or objects included. the member of."

Name Bind to Object This concept can be seen everywhere in Python, which is one of the most basic and most important concepts of Python. If you don't understand this, some unexpected results will quietly appear in your code.

Let's take a simple example first:

>>> a = {'g': 1} >>> b = a * 4 >>> Print B [{'g': 1}, {'g': 1}, {'g': 1}, {'g': 1}] >>> b [0] ['g'] = 2 >>> Print B

What is unexpected? Please read this article slowly.

1. Object "Everything is object", which is the concept of Python's object-oriented language. In the C we are familiar with, 1 is just a whole, not an object. But in Python, 1 is a real object, you can use DIR (1) to display its properties.

In Python, all objects have the following three characteristics: * Unique identification code (Identity) * type * content (or value)

Once the object is created, its identification code is not allowed to change. The object's identification code can have built-in functions ID (), which is an integer. You can imagine the address of the object in memory, in fact, in the current implementation of the scales are the memory address of the object.

>>> Class C1: Pass ... >>> OBJ = C1 () >>> OBJ <__ main __. c1 instance at 0x00ac0738 >>>> ID (OBJ) 11274040

Conversion, 11274040 is the 0x00ac0738 of hexadecimal.

>>> ID (1) 7957136

This is the identification code of the 1 object mentioned earlier, that is, its address in memory.

When comparing two objects with the IS operator, they are comparing their identification codes. More specifically, the IS operator is to determine whether the two objects are the same object. >>> [1] IS [1] The result is false because it is two different objects, stored in different places in memory.

>>> [1] == [1] The result is TRUE because the two different objects have the same value.

Similar to the identification code of the object, the type of object is not changeable. You can use the internal function type () to acquire the type of object.

The value of some objects can be changed, such objects are called variable objects; while other objects are not changeable (such as 1 object) after creating, such objects are called constant objects. The variability of the object is determined by its type, such as a numerical type, string, and tuple's object is a constant object; the word typical (Dictionary) and list type (LIST) Objects are variable objects. In addition to the three features mentioned above, an object may: * No or have multiple methods * No or multiple names

2. The name name is the title of an object, and an object can only have one name or no name or take multiple names. But the object you don't know how many names, what is called, only the name itself knows what object it points to. Take an action to take a name of a name called naming, Python will assign a name to be a naming operation (or name binding).

The name is valid in a certain name space, and unique, it is impossible to take the same name in two or more objects in the same name space.

Let's take a look at the first example of this article: i = 1. In Python, it has the following two meanings: * Creating a value of 1 value * "i" is the name of the integer object (and it is a reference) 3. Binding as above, tied Table is to link an object with a name. More specifically, it is to increase the reference count of the object. As we all know, a big problem in C is that memory leaks - that is, the dynamically allocated memory is not recycled, and one of the tools to solve this problem is the reference count. Python uses this technology to achieve its garbage collection mechanism. All objects in Python have a reference count.

i = i 1

* This creates a new object whose value is i 1. * "i" This name points to the newly built object, the reference count of the object plus one, and the reference to the old object to be directed before "i" is reduced. * The value of the old object points to "i" does not change. * This is why there is no in Python, - a reason for such a single operator.

3.1 Reference counting counts The counting count will increase in the following cases: * Assignment operation * In one container (list, sequence, dictionary, etc.) including this object

The reference count count of the object will decrease in the following cases: * Leave the current namespace (the local name in this name space will be destroyed) * One name of the object is bound to another object * object from the container containing it Removing * The name is displayed in Del (such as: Del i)

When the reference count of the object is reduced to 0, the object will be destroyed, and the memory it occupies will be reclaimed.

4. Some of the strange phenomena brought by the name binding

Example 4.1: >>> Li1 = [7, 8, 9, 10] >>> Li2 = Li1 >>> Li1 [1] = 16 >>> Print Li2 [7, 16, 9, 10]

Note: Both Li1 and Li2 point to the same list object [7, 8, 9, 10], "Li [1] = 16" is the second element in this list, so it will also see this by Li2. A change.

Example 4.2: >>> b = [{'g': 1}] * 4 >>> Print B [{'g': 1}, {'g': 1}, {'g': 1}, { 'g': 1}] >>> b [0] ['g'] = 2 >>> Print B [{'g': 2}, {'g': 2}, {'g': 2} , {'g': 2}] Example 4.3: >>> b = [{'g': 1}] [{'g': 1}] [{'g': 1}] [{' G ': 1}] >>> Print B [{' g ': 1}, {' g ': 1}, {' g ': 1}, {' g ': 1}] >>> b [0 ] ['g'] = 2 >>> Print B [{'g': 2}, {'g': 1}, {'g': 1}, {'g': 1}]

Note: The multiplication symbol (*) is equivalent to the repetition of several additions in the Python book, that is, the example 4.2 should be consistent with the result of 4.3. actually not. Each element in this list in Example 4.2 is {'g': 1} is actually the same object, and it can be verified by ID (B [N]). In the Example 4.3, it is four different objects. We can use the name binding method to eliminate this ambiguity:

>>> a = {'g': 1} >>> b = [a] * 4 >>> b [0] ['g'] = 2 >>> Print B [{'g': 2}, {'g': 2}, {'g': 2}, {'g': 2}] >>> Print A {'g': 2}

>>> a = {'g': 1} >>> b = [A] [a] [a] [a] >>> b [0] ['g'] = 2 >>> print B [{'g': 2}, {'g': 2}, {'g': 2}, {'g': 2}] >>> Print A {'g': 2}

However, the effect of "*" and continuous addition is the same for constant objects. For example, b = [1] * 4 is equivalent to B = [1] [1] [1] [1].

5. The parameter transfer of the function of the function of the function is also a binding process of the name and object, and is bound to another name space (ie the name space inside the function). What is the impact of Python's unique view of the assignment statement?

5.1 pass value? Address? When learning C , we all know that there are two parameters transfer mode: pass value and address. All parameter passes in Python is reference only, that is, an address. This is because the name is a reference to this Python's characteristics of the object, and it will definitely change it to a function in the function body. Let's take a look at this example: Example 5.1 >>> A = [1, 2, 3] >>> DEF FOO (PAR): ... PAR [1] = 10 ... >>> foo (a ) >>> Print A [1, 10, 3]

Therefore, in Python, we should throw away the concept of passing parameters, and the time to keep in mind the function's call parameters is bound to the name of another name space. In the function, it is used to use another name, but it is still an operation of this.

5.2 Default parameters use default parameters is a kind of practice for our favorite. This can save a lot of keystrokes when calling the function, and the code is even more concise. More importantly, it reflects the original intention of this function design from a sense. However, the default parameters in Python have hidden a mystery, and beginners will definitely plant their heads, and this error is very hidden. Let's take a look at the example below:

Example 5.2 >>> Def foo (PAR = []): ... par.append (0) ... Print par ... >>> foo () # First call [0] >>> foo ) # 第二 第二 调 [0, 0]

What went wrong? This parameter PAR seems to be similar to the static variables in C, accumulated the previous results. Is that right? Of course, this is the "object, name, binding" these thoughts violation. "Everything is object", remember? Here, the function foo is of course an object, which can be called a function object (there is nothing different from the general object). Let's take a look at what this object is.

>>> dir (foo) [ '__ call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__module__', '__name__ ',' __new__ ',' __reduce__ ',' __reduce_ex__ ',' __repr__ ',' __setattr__ ',' __str__ ',' func_closure ',' func_code ',' func_defaults', 'func_dict', 'func_doc', 'func_globals', 'FUNC_NAME']

From the name, "FUNC_DEFAULTS" is likely to be related to the default parameter to see its value.

>>> foo.func_defaults # Display this property content ([0, 0],) >>> foo () # Third call [0, 0, 0] >>> fuNC_DEFAULTS #Cook this property ([0, 0, 0],) is unlikely, that is, this sequence object (tuple) contains all default parameters. Verify:

>>> DEF FOOM (PAR1, DEF1 = 1, DEF2 = [], DEF3 = 'str'): # Defines a function with multiple default parameters ... Def2.append (0) ... Print Par1, DEF1, DEF2, DEF3 ... >>> Foom.Func_Defaults (1, [], 'str')

There are several default parameters in the function definition, and several objects are included in FUNC_DEFAULTS, which is temporarily called default parameter objects (such as 1, [], and 'str' in the above). The lifecycle of these default parameter objects is the same as the function object, starting from the function using the DEF definition until it is dying (such as using DEL). So even if these functions are not called, the default parameter object will always exist.

As mentioned earlier, the process called by the function is the binding process of the object in another name space. When the function is called, if no parameters are delivered to this default parameter, the name of this default parameter is bound to a corresponding default parameter object in FUNC_DEFAULTS. >>> FOOM (2) The name DEF1 in FOOM will bind to the first object in FUNC_DEFAULTS, and DEF2 is bound to the second, and DEF3 is the third. So we see the accumulated phenomenon that appears in the function foo, because PAR is bound to the default parameter object, and it is a variable object (list), par.append (0) will change this default each time The content of the parameter object.

Improve the function foo, it may be easier to help understand: >>> Def foo (PAR = []): ... Print ID (PAR) # View the identification code of the object ... par.Append (0). .. print par ... >>> foo.func_defaults # The initial value of the default parameter object ([],) >>> ID (foo.func_defaults [0]) # View the identification code of the first default parameter object 11279792 # Your results may be different >>> Foo () 11279792 # Proof PAR binding object is the first default parameter object [0] >>> foo () 11279792 # still bind to the first default Parameter object [0, 0] # This object changes in this object >>> b = [1] >>> ID (b) 1127952 >>> FOO (b) # 不用 不用 1279952 # Name PAR tied The identical object is bound to the same object [1, 0] >>> foo.func_defaults ([0, 0],) # default parameter object is still there, and the value does not change> >> foo () 11279792 # Name PAR is binding to the default parameter object ([0, 0, 0], in order to prevent such "problem", Python recommends the following methods: >>> Def foo PAR = []): ... if Par is none: ... par = [] ... par.append (0) ... Print Par

Use none as a sentinel to determine if there is a parameter incoming, and if not, a new list object is newly created instead of binding to the default parameter object.

6. Summary * Python is a purely object-oriented language. * Assigning statements are the binding process of the name and object. * The transfer of functions is the binding of objects to different namespaces.

7. Reference * "Dive Into Python", Mark Pilgrim, http://diveintopython.org, 2003. * "Python Objects", Fredrik Lundh, http://www.effbot.org/zone/python-Objects.htm. * "An Introduction to Python", David M. Beazley, http://systems.cs.uchicago.idu/~Beazley/Tutorial/Beazley_Intro_python/intropy.pdf. * You can learn all about Python from the official website of Python (http://www.python.org).

转载请注明原文地址:https://www.9cbs.com/read-21950.html

New Post(0)