Objets, noms et liaisons Python

大家讲道理
Libérer: 2017-05-28 10:00:57
original
1520 Les gens l'ont consulté

PythonAvancé - Objet, nom et liaison

sont écrits devant

Sauf indication contraire, les éléments suivants sont basés sur Python3

1. Tout est un objet

Python philosophie :

Tout en Python est un objet

1.1 Données Modèle - les objets, les valeurs et les types

les objets sont Python des abstractions de données. PythonToutes les données du programme sont représentées par des objets ou des relations entre objets. (Dans un sens, pour se conformer au modèle « d'ordinateur de stockage » de von Neumann, le code dans Python est également un objet.) Chaque objet dans

Python a une identité, une valeur et un type. Une fois qu'un objet est créé, son identité ne change jamais ; vous pouvez considérer l'identité comme l'adresse de l'objet en mémoire. L'opérateur is compare les identités de deux objets ; la fonction id() renvoie un entier représentant l'identité de l'objet.

Détails de l'implémentation de CPython : Dans l'implémentation de l'interpréteur CPython, la fonction id(x) renvoie l'adresse mémoire où x est stocké

Le type de l'objet détermine l'objet. Les opérations prises en charge (par exemple, l'objet a-t-il une longueur ?) déterminent également les valeurs possibles pour les objets de ce type. type()La fonction renvoie le type d'objet (ce type lui-même est aussi un objet). Comme son identité, le type d'un objet est immuable [1].

Les valeurs de certains objets peuvent être modifiées. Les objets dont les valeurs peuvent changer sont aussi appelés mutables ; une fois créés, les objets dont les valeurs sont constantes sont également appelés immuables . (Lorsqu'un objet conteneur immuable contient une référence à un objet mutable, lorsque la valeur de l'objet mutable change, la valeur de l'objet conteneur immuable est également modifiée ; cependant, l'objet conteneur immuable est toujours considéré comme immuable, car la collection Les valeurs contenues par l'objet sont en effet immuables. Par conséquent, l'immuabilité n'est pas strictement équivalente à avoir des valeurs immuables. C'est subtil) (Annotation : Premièrement, la valeur d'un objet conteneur immuable est une collection, une collection. contient des références à. d'autres objets ; alors ces références peuvent être considérées comme des adresses. Même si le contenu pointé par l'adresse change, l'adresse elle-même dans la collection ne change pas, donc l'objet conteneur immuable est toujours un objet immuable. Par exemple, les nombres, les chaînes et les tuples sont immuables, mais les dictionnaires et les listes sont mutables. Les objets ne sont jamais explicitement détruits ; ils sont collectés lorsqu'ils deviennent inaccessibles. Une implémentation d'interpréteur permet de retarder ou d'ignorer complètement le garbage collection - en fonction de la façon dont le garbage collection est implémenté, tant qu'aucun objet accessible n'est collecté.

Détails de l'implémentation de CPython :

L'implémentation de l'interpréteur utilise le mode de comptage de références pour retarder la détection des bouclesCPython déchets de liens. Cette méthode peut recycler la plupart des objets inaccessibles. Il n'y a aucune garantie que les déchets référencés par le cycle seront recyclés. Consultez la documentation du module pour plus d'informations sur le contrôle du garbage collection cyclique. D'autres implémentations d'interpréteur diffèrent de , et les implémentations de gc pourraient changer à l'avenir. Par conséquent, on ne peut pas compter sur le garbage collector pour récupérer des objets inaccessibles (les objets fichier doivent donc toujours être fermés explicitement). CPythonCPythonIl convient de noter que l'utilisation de la fonction de suivi de

débogage

de l'outil peut faire en sorte que les objets qui doivent être recyclés restent vivants. L'utilisation de l'instruction try pour intercepter les exceptions peut. conservez également la Survie de l'objet. ...exceptCertains objets font référence à des ressources externes telles que des fichiers ou des fenêtres. Il va sans dire qu'une fois que l'objet contenant la ressource a été récupéré, la ressource sera également libérée. Cependant, comme il n'existe aucun mécanisme garantissant que la récupération de place aura lieu définitivement, ces objets contenant des ressources fournissent également un moyen de libérer explicitement des objets externes. ressources, généralement en utilisant la

Méthode. Il est fortement recommandé de libérer les ressources explicitement dans le programme. Déclaration

close()<a href="http://www.php.cn/wiki/207.html" target="_blank">final<code>tryly et ... Les instructions facilitent la libération des ressources. <a href="http://www.php.cn/wiki/207.html" target="_blank">final</a>ly

Certains objets contiennent des références à d'autres objets, ces objets sont appelés Conteneurs. Les tuples, les listes et les dictionnaires sont tous des conteneurs. Partie de la valeur du conteneur référencée. La plupart du temps, lorsque nous parlons de la valeur d'un conteneur, nous faisons référence à l'ensemble des valeurs d'objet que le conteneur contient, plutôt qu'à l'ensemble des identités des objets. Cependant, lorsque nous parlons de la mutabilité d'un conteneur, nous impliquons les identités des objets qu'il contient. Par conséquent, si un objet immuable (tel qu'un tuple) contient une référence à un objet mutable, lorsque l'objet mutable change, sa valeur change également.

Les types affectent la plupart des comportements d'un objet. Dans certains cas, même l'importance de l'identité de l'objet est affectée : pour les types immuables, l'opération de calcul d'une nouvelle valeur peut en fait renvoyer une référence à un objet existant avec la même valeur et le même type, alors que pour les objets mutables, cela est impossible. Par exemple, une fois l'instruction a = 1; b = 1 exécutée, a et b peuvent ou non faire référence au même objet avec la même valeur, selon l'implémentation de l'interpréteur. Mais une fois l'instruction c = []; d = [] exécutée, il est garanti que c et d pointeront vers des listes vides nouvellement créées différentes et uniques. (Notez que c = d = [] attribue le même objet à c et d)

Remarque : Ce qui précède est traduit de "Les références Python Language #Données modèle# Objets, valeurs, types》Version 3.6.1.

1.2 Résumé de l'objet

Le document officiel a décrit l'Python objet en détail. Voici un résumé.

Trois caractéristiques des objets :

  • Identité
    Identifie l'objet de manière unique CPython L'interpréteur est implémenté en tant qu'objet ; adresse mémoire.
    Opération : id(), fonction intégrée id() la fonction renvoie un entier qui identifie l'objet is compare les identités de deux objets.
    Exemple :

    >>> id(1)
    1470514832
    >>> 1 is 1
    True
    Copier après la connexion
  • Le type
    détermine les opérations supportées par l'objet, valeurs possibles immuables ;
    Opération : type(), la fonction intégrée renvoie le type d'objet
    Exemple :

    >>> type('a')
    <class></class>
    Copier après la connexion
  • Valeur
    données, mutable/immuable
    Opération : L'opérateur == est utilisé pour comparer si les valeurs de deux objets sont égales. D'autres opérateurs de comparaison comparent la taille des objets.
    Exemple :

    >>> 'python'
    'python'
    >>> 1 == 2
    False
    Copier après la connexion

Mutable et immuable  : On pense généralement que les objets à valeurs immuables sont des objets immuables, et les objets à valeurs variables Il s'agit d'un objet mutable, mais veuillez noter que l'objet de collection immuable contient des membres de référence d'objet mutables. Objets dans

Python :


# -*- coding: utf-8 -*-# filename: hello.py&#39;a test module&#39;author = &#39;Richard Cheng&#39;import sysclass Person(object):    &#39;&#39;&#39; Person class&#39;&#39;&#39;

    def init(self, name, age):        self.name = name        self.age = agedef tset():    print(sys.path)
    p = Person(&#39;Richard&#39;, 20)    print(p.name, &#39;:&#39;, p.age)def main():
    tset()if name == &#39;main&#39;:
    main()
Copier après la connexion


Ce paragraphePython Il y a de nombreux objets dans le code, y compris l'objet module hello, l'objet de classe Person créé, plusieurs fonctions telles que test, main objets fonction, des nombres, des chaînes, et même le code lui-même est également un objet.

2. Le nom est "Variable"

Il existe un mot pour "variable" dans presque toutes les langues, à proprement parler, la variable dans Python ne devrait pas. être appelé Les variables sont appelées de manière plus appropriée noms.

La traduction suivante est tirée de Code Like a Pythonista : Python idiomatique # Python a des "noms"

2.1 D'autres langages ont des variables

Dans d'autres langages, attribuer une valeur à une variable c'est comme La valeur est placée dans la "boîte".
int a = 1;

Objets, noms et liaisons Python

La case a a désormais un entier 1.

Remplacez le contenu de la boîte en attribuant une valeur à la même variable :
a =2;

Objets, noms et liaisons Python

Maintenant la boîte a contient un entier2

Attribuez une variable à une autre, copiez la valeur de la variable et mettez-la dans la nouvelle case :
int b = a;

Objets, noms et liaisons Python

Objets, noms et liaisons Python

b est la deuxième case, contenant une copie de l'entier 2. La boîte a possède un exemplaire séparé.

2.2 Python a des noms Dans

Python, un nom ou un identifiant revient à lier une étiquette à un objet.
a = 1

Objets, noms et liaisons Python

这里,整数对象1有一个叫做a的标签。

如果重新给a分配值,只是简单的将标签移动到另一个对象:
a = 2

Objets, noms et liaisons Python
Objets, noms et liaisons Python

现在名字a贴到了整数对象2上面。原来的整数对象1不再拥有标签a,或许它还存在,但是不能通过标签a访问它了(当对象没有任何引用时,会被回收。)

如果将一个名字分配给另一名字,只是将另一个名字标签捆绑到存在的对象上:
b = a

Objets, noms et liaisons Python

名字b只是绑定到与a引用的相同对象上的第二个标签而已。

虽然在Python中普遍使用“变量”(因为“变量”是普遍术语),真正的意思是名字或者标识符。Python中的变量是值得标签,不是装值得盒子。

2.3 指针?引用?名字?

C/C++中有指针,Java中有引用,Python中的名字在一定程度上等同于指针和引用。

2.1节中其他语言的例子,也只是针对于它们的基本类型而言的,若是指针或者引用,表现也跟Python的名字一样。这也在一定程度上说明了Python面向对象贯彻得更加彻底。

2.4 名字支持的操作

可以对一个变量做什么?声明变量,使用变量,修改变量的值。名字作为Python中的一个重要概念,可以对它做的操作有:

  • 定义;名字需要先定义才能使用,与变量需要先声明一样。

  • 绑定:名字的单独存在没有意义,必须将它绑定到一个对象上。

  • Objets, noms et liaisons Python:名字可以重新引用另一个对象,这个操作就是Objets, noms et liaisons Python。

  • 引用:为什么要定义名字,目的是使用它。

3、绑定的艺术

名字以及对象,它们之间必然会发生些什么。

3.1 变量的声明

其他如C/C++Java的高级语言,变量在使用前需要声明,或者说定义。以下在Java中声明变量:


public static void main(String[] args) {        int i = 0; // 先声明,后使用
        System.out.println(i); // 使用变量i}
Copier après la connexion


这样,在可以访问到变量i所在作用域的地方,既可以使用i了。还有其他声明变量的方法么?好像没有了。

3.2 名字的定义

Python中有多种定义名字的途径,如函数定义,函数名就是引用函数对象的名字;类定义,类名就是指向类对象的名字,模块定义,模块名就是引用模块对象的名字;当然,最直观的还是赋值语句。

赋值语句

官方对赋值语句做了这样的说明(地址):

Assignment statements are used to (re)bind names to values and to modify attributes or items of mutable objects.

即:

赋值语句被用来将名字绑定或者Objets, noms et liaisons Python给值,也用来修改可变对象的属性或项

那么,我们关心的,就是赋值语句将名字和值(对象)绑定起来了。

看一个简单的赋值语句:


a = 9
Copier après la connexion


Python在处理这条语句时:

  1. 首先在内存中创建一个对象,表示整数9:

Objets, noms et liaisons Python

  1. 然后创建名字a,并把它指向上述对象:

Objets, noms et liaisons Python

上述过程就是通过赋值语句的名字对象绑定了。名字首次和对象绑定后,这个名字就定义在当前命名空间了,以后,在能访问到这个命名空间的作用域中可以引用该名字了。

3.3 引用不可变对象

定义完名字之后,就可以使用名字了,名字的使用称为“引用名字”。当名字指向可变对象和不可变对象时,使用名字会有不同的表现。


a = 9       #1a = a + 1   #2
Copier après la connexion


语句1执行完后,名字a指向表示整数9的对象:

Objets, noms et liaisons Python

由于整数是不可变对象,所以在语句2处引用名字a,试图将表示整数9的对象 + 1,但该对象的值是无法改变的。因此就将该对象表示的整数值91,以整数10新建一个整数对象:

Objets, noms et liaisons Python

接下来,将名字a Objets, noms et liaisons Python 到新建对象上,并移除名字对原对象的引用:

Objets, noms et liaisons Python

使用id()函数,可以看到名字a指向的对象地址确实发生了改变:


>>> a = 9>>> id(a)1470514960>>> a = a + 1>>> id(a)1470514976
Copier après la connexion


3.4 引用可变对象
3.4.1 示例1:改变可变对象的值

可变对象可以改变其值,并且不会造成地址的改变:


>>> list1 = [1]>>> id(list1)42695136>>> list1.append(2)>>> id(list1)42695136>>> list1
[1, 2]>>>
Copier après la connexion


执行语句list1 = [1],创建一个list对象,并且其值集中添加1,将名字list1指向该对象:

Objets, noms et liaisons Python

执行语句list1.append(2),由于list是可变对象,可以直接在其值集中添加2

Objets, noms et liaisons Python

值得改变并没有造成list1引用的对象地址的改变。

3.4.2 示例2:可变对象Objets, noms et liaisons Python

再来看一个比较“奇怪”的例子:


values = [1, 2, 3]
values[1] = valuesprint(values)
Copier après la connexion


一眼望去,期待的结果应该是


[1, [1, 2, 3], 3]
Copier après la connexion


但实际上结果是:


[1, [...], 3]
Copier après la connexion


我们知道list中的元素可以是各种类型的,list类型是可以的:

Objets, noms et liaisons Python

3.4.3 示例3:Objets, noms et liaisons Python可变对象

观察以下代码段:


>>> list1 = [1]>>> id(list1)42695136>>> list1 = [1, 2]>>> id(list1)42717432
Copier après la connexion


两次输出的名字list1引用对象的地址不一样,这是因为第二次语句list 1 = [1, 2] 对名字做了Objets, noms et liaisons Python:

Objets, noms et liaisons Python

3.5 共享对象

当两个或两个以上的名字引用同一个对象时,我们称这些名字共享对象。共享的对象可变性不同时,表现会出现差异。

3.5.1 共享不可变对象

函数attempt_change_immutable将参数i的值修改为2


def attempt_change_immutable(i):
    i = 2i = 1print(i)
attempt_change_immutable(i)print(i)
Copier après la connexion


Output:


11
Copier après la connexion


如果你对输出不感到意外,说明不是新手了 ^_^。

  1. 首先,函数的参数i与全局名字i不是在同一命名空间中,所以它们之间不相互影响。

  2. 调用函数时,将两个名字i都指向了同一个整数对象。

  3. 函数中修改i的值为2, 因为整数对象不可变,所以新建值为2的整数对象,并把函数中的名字i绑定到对象上。

  4. 全局名字i的绑定关系并没有被改变。

Objets, noms et liaisons Python

Objets, noms et liaisons Python

值得注意的是,这部分内容与命名空间和作用域有关系,另外有文章介绍它们,可以参考。

3.5.2 Objets, noms et liaisons Python

函数attempt_change_mutable为列表增加字符串。


def attempt_change_mutable(list_param):
    list_param.append(&#39;test&#39;)

list1 = [1]print(list1)
attempt_change_mutable(list1)print(list1)
Copier après la connexion


output:


[1]
[1, &#39;test&#39;]
Copier après la connexion


可以看到函数成功改变了列表list1的值。传递参数时,名字list_param引用了与名字list1相同的对象,这个对象是可变的,在函数中成功修改了对象的值。

首先,名字list_param与名字list1指向对象:

Objets, noms et liaisons Python

然后,通过名字list_param修改了对象的值:

Objets, noms et liaisons Python

最后,这个修改对名字list1可见。

3.6 绑定何时发生

总的来说,触发名字对象绑定的行为有以下一些:

  • 赋值操作;a = 1

  • 函数定义;

    def test():
        pass
    Copier après la connexion

    将名字test绑定到函数对象

  • 类定义:

    class Test(object):
        pass
    Copier après la connexion

    将名字Test绑定到类对象

  • 函数传参;

    def test(i):
        pass
    test(1)
    Copier après la connexion

    将名字i绑定到整数对象1

  • import语句:

    import sys
    Copier après la connexion

    将名字sys绑定到指定模块对象。

  • <a href="http://www.php.cn/wiki/125.html" target="_blank">for</a>循环

    for i in range(10):
        pass
    Copier après la connexion

    每次循环都会绑定/Objets, noms et liaisons Python名字i

  • as操作符

    with open(&#39;dir&#39;, &#39;r&#39;) as f:
        pass
    
    try:
        pass
    except NameError as ne:
        pass
    Copier après la connexion

    with open语句,异常捕获语句中的as都会发生名字的绑定

    4、其他说明

    待续。。。

    参考

    1. The Python Language References#Data model# Objects, values, types

    2. Python的名字绑定

    3. Python一切皆对象

    4. Code Like a Pythonista: Idiomatic Python

    5. python基础(5):深入理解 python 中的赋值、引用、拷贝、作用域

    脚注

    [1] 在特定的控制条件下,改变对象的类型是可能的。但不是一种明智的做法,如果处理不当的话,会发生一些奇怪的行为。

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal