Table des matières
从解释器的角度看对象的调用
下面我们可以做总结了,通过类型对象去创建实例对象的整体流程如下:
Maison développement back-end Tutoriel Python Comment les objets Python sont appelés

Comment les objets Python sont appelés

May 31, 2023 am 11:39 AM
python

Wedge

Nous avons appris qu'il existe deux manières principales de créer des objets : l'une via l'API Python/C et l'autre en appelant un objet de type. Pour les objets d'instance de types intégrés, les deux méthodes sont prises en charge. Par exemple, les listes peuvent être créées via [] ou list(). La première est une API Python/C et la seconde est un objet de type appelant.

La création d'un objet instance d'une classe personnalisée ne peut être effectuée qu'en appelant l'objet type de la classe. Un objet est appelable s’il peut être appelé, sinon il ne l’est pas.

Le fait qu'un objet soit appelable dépend du fait que son objet de type correspondant définit ou non des méthodes spécifiques. Si vous la regardez du point de vue de Python, cette méthode est __call__, et du point de vue de l'interprète, cette méthode est tp_call.

En regardant les appels d'objets d'un point de vue Python

Call int, str, tuple peut créer un entier, une chaîne, un tuple, appeler une classe personnalisée peut également créer l'objet d'instance correspondant, indiquant que les objets de type peuvent être appelés, c'est-à-dire , appelable. Ensuite, il doit y avoir une méthode __call__ à l'intérieur de l'objet type (type) de ces objets type (int, str, tuple, classe, etc.).

# int可以调用
# 那么它的类型对象、也就是元类(type), 内部一定有__call__方法
print(hasattr(type, "__call__"))# True
# 而调用一个对象,等价于调用其类型对象的 __call__ 方法
# 所以 int(3.14)实际就等价于如下
print(type.__call__(int, 3.14))# 3
Copier après la connexion

Remarque : la description ici peut être un peu déroutante. Nous disons que int, str et float sont tous des objets de type (en termes simples, des classes), et 123, "Hello" et 3.14 sont leurs objets d'instance correspondants. Aucun problème. Mais le type est-il un objet de type ? Évidemment oui, même si nous l'appelons une métaclasse, c'est aussi un objet de type. Si print(type) affiche une classe, c'est aussi un objet de type.

Donc, par rapport au type, int, str et float sont-ils redevenus des objets d'instance ? Parce que leur type est le type.

La classe a donc une dualité :

  • Si vous vous situez du point de vue d'objets d'instance (tels que : 123, "satori", [], 3.14), c'est un objet de type

  • Si vous vous situez du point de vue du type Du point de vue du type, c'est un objet d'instance

De même, le type de type est également un type, alors le type est à la fois un objet de type de type et le type est également un objet d'instance de type . Même si la description est quelque peu compliquée, elle ne devrait pas être difficile à comprendre. Pour éviter toute ambiguïté dans les descriptions ultérieures, une déclaration est faite ici :

  • entiers, nombres à virgule flottante, chaînes, etc., nous les appelons objets d'instance

  • int, float, str, dict et les nôtres La classe définie est appelée un objet de type

  • type Bien qu'il s'agisse également d'un objet de type, nous l'appelons une métaclasse

Il y a donc une méthode __call__ à l'intérieur du type, ce qui signifie que tous les objets de type sont appelables. Oui, car appeler un objet type appelle la méthode __call__ de type. La possibilité d'appeler l'objet instance n'est pas nécessairement déterminée. Cela dépend si la méthode __call__ est définie dans son objet type, car l'appel d'un objet exécute essentiellement la méthode __call__ à l'intérieur de son objet type.

class A:
 pass
a = A()
# 因为我们自定义的类 A 里面没有 __call__
# 所以 a 是不可以被调用的
try:
 a()
except Exception as e:
 # 告诉我们 A 的实例对象不可以被调用
 print(e)# 'A' object is not callable
# 如果我们给 A 设置了一个 __call__
type.__setattr__(A, "__call__", lambda self: "这是__call__")
# 发现可以调用了
print(a())# 这是__call__
Copier après la connexion

Nous voyons que c'est la caractéristique des langages dynamiques Même après la création de la classe, elle peut toujours être définie dynamiquement via le type, ce qui n'est pas pris en charge dans les langages statiques. Type est donc la métaclasse de toutes les classes, qui contrôle le processus de génération de nos classes personnalisées. Type, une classe ancienne et puissante, nous permet de jouer de nombreuses nouvelles astuces.

Étant donné que les classes intégrées sont définies statiquement au niveau inférieur, vous ne pouvez pas utiliser le type pour ajouter, supprimer ou modifier dynamiquement des propriétés. Parce que nous pouvons voir dans le code source que ces classes intégrées, y compris les métaclasses, sont toutes des objets PyTypeObject et ont été déclarées comme variables globales au niveau inférieur, ou qu'elles existent déjà en tant que classes statiques. Bien que le type soit la métaclasse de tous les types d'objets, il ne peut être ajouté, supprimé et modifié que lorsqu'il s'agit de nos classes personnalisées.

Et nous avons également expliqué que la nature dynamique de Python est attribuée dynamiquement lorsque l'interpréteur traduit le bytecode en code C. Par conséquent, la définition dynamique d'attributs ou de méthodes pour les classes ne s'applique qu'aux classes dynamiques, c'est-à-dire dans les fichiers py définis. en utilisant le mot-clé class.

Pour les classes statiques ou les classes d'extension définies lors de l'écriture des modules d'extension (les deux sont équivalentes), elles pointent déjà vers des structures de données de niveau C après compilation et n'ont pas besoin d'être interprétées par l'interpréteur. Par conséquent, l'interpréteur ne peut naturellement pas falsifier. avec eux. Après tout, une vie forte n’a pas besoin d’explication.

try:
 type.__setattr__(dict, "__call__", lambda self: "这是__call__")
except Exception as e:
 print(e)# can't set attributes of built-in/extension type 'dict'
Copier après la connexion

Nous avons vu une exception levée, nous invitant que nous ne pouvons pas définir d'attributs pour le dict de type intégré/étendu, car ils contournent l'étape d'interprétation et d'exécution de l'interpréteur, de sorte que leurs attributs ne peuvent pas être définis dynamiquement.

La même chose est vraie pour les objets d'instance. Les objets d'instance de classes statiques ne peuvent pas définir d'attributs de manière dynamique :

class Girl:
 pass
g = Girl()
g.name = "古明地觉"
# 实例对象我们也可以手动设置属性
print(g.name)# 古明地觉
lst = list()
try:
 lst.name = "古明地觉"
except Exception as e:
 # 但是内置类型的实例对象是不可以的
 print(e)# 'list' object has no attribute 'name'
Copier après la connexion

Certaines personnes peuvent être surprises, pourquoi les listes ne le peuvent-elles pas ? La réponse est que l'objet instance du type intégré n'a pas de dictionnaire d'attributs __dict__, car les attributs ou méthodes pertinents ont été définis en bas et ne peuvent pas être ajoutés dynamiquement. Lorsque nous définissons l'attribut __slots__ pour une classe personnalisée, cela aura le même effet que la classe intégrée.

Bien sûr, nous expliquerons plus tard comment changer cela en modifiant dynamiquement l'interpréteur. Par exemple, cela ne signifie-t-il pas que les classes statiques ne peuvent pas définir les propriétés de manière dynamique ? Maintenant, je vais me gifler :

import gc
try:
 type.__setattr__(list, "ping", "pong")
except TypeError as e:
 print(e)# can't set attributes of built-in/extension type 'list'
# 我们看到无法设置,那么我们就来改变这一点
attrs = gc.get_referents(tuple.__dict__)[0]
attrs["ping"] = "pong"
print(().ping)# pong
attrs["append"] = lambda self, item: self + (item,)
print(
 ().append(1).append(2).append(3)
)# (1, 2, 3)
Copier après la connexion

我脸肿了。好吧,其实这只是我们玩的一个小把戏,当我们介绍完整个 CPython 的时候,会来专门聊一聊如何动态修改解释器。比如:让元组变得可修改,让 Python 真正利用多核等等。

从解释器的角度看对象的调用

我们以内置类型 float 为例,我们说创建一个 PyFloatObject,可以通过3.14或者float(3.14)的方式。前者使用Python/C API创建,3.14直接被解析为 C 一级数据结构,也就是PyFloatObject实例;后者使用类型对象创建,通过对float进行一个调用、将3.14作为参数,最终也得到指向C一级数据结构PyFloatObject实例。

Python/C API的创建方式我们已经很清晰了,就是根据值来推断在底层应该对应哪一种数据结构,然后直接创建即可。我们重点看一下通过类型调用来创建实例对象的方式。

如果一个对象可以被调用,它的类型对象中一定要有tp_call(更准确的说成员tp_call的值是一个函数指针,不可以是0),而PyFloat_Type是可以调用的,这就说明PyType_Type内部的tp_call是一个函数指针,这在Python的层面上我们已经验证过了,下面我们再来通过源码看一下。

//typeobject.c
PyTypeObject PyType_Type = {
 PyVarObject_HEAD_INIT(&PyType_Type, 0)
 "type", /* tp_name */
 sizeof(PyHeapTypeObject), /* tp_basicsize */
 sizeof(PyMemberDef),/* tp_itemsize */
 (destructor)type_dealloc, /* tp_dealloc */
 //... /* tp_hash */
 (ternaryfunc)type_call, /* tp_call */
 //...
}
Copier après la connexion

我们看到在实例化PyType_Type的时候PyTypeObject内部的成员tp_call被设置成了type_call。当 PyFloat_Type 被调用时, type_call 指向的函数将会被触发,因为它是一个函数指针。

因此 float(3.14) 在C的层面上等价于:

(&PyFloat_Type) -> ob_type -> tp_call(&PyFloat_Type, args, kwargs);
// 即:
(&PyType_Type) -> tp_call(&PyFloat_Type, args, kwargs);
// 而在创建 PyType_Type 的时候,给 tp_call 成员传递的是 type_call
// 因此最终相当于
type_call(&PyFloat_Type, args, kwargs)
Copier après la connexion

如果用 Python 来演示这一过程的话:

# float(3.14),等价于
f1 = float.__class__.__call__(float, 3.14)
# 等价于
f2 = type.__call__(float, 3.14)
print(f1, f2)# 3.14 3.14
Copier après la connexion

这就是 float(3.14) 的秘密,相信list、dict在实例化的时候是怎么做的,你已经猜到了,做法是相同的。

# lst = list("abcd")
lst = list.__class__.__call__(list, "abcd")
print(lst)# ['a', 'b', 'c', 'd']
# dct = dict([("name", "古明地觉"), ("age", 17)])
dct = dict.__class__.__call__(dict, [("name", "古明地觉"), ("age", 17)])
print(dct)# {'name': '古明地觉', 'age': 17}
Copier après la connexion

最后我们来围观一下 type_call 函数,我们说 type 的 __call__ 方法,在底层对应的是 type_call 函数,它位于Object/typeobject.c中。

static PyObject *
type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
 // 如果我们调用的是 float
 // 那么显然这里的 type 就是 &PyFloat_Type

 // 这里是声明一个PyObject *
 // 显然它是要返回的实例对象的指针
 PyObject *obj;

 // 这里会检测 tp_new是否为空,tp_new是什么估计有人已经猜到了
 // 我们说__call__对应底层的tp_call
 // 显然__new__对应底层的tp_new,这里是为实例对象分配空间
 if (type->tp_new == NULL) {
 // tp_new 是一个函数指针,指向具体的构造函数
 // 如果 tp_new 为空,说明它没有构造函数
 // 因此会报错,表示无法创建其实例
 PyErr_Format(PyExc_TypeError,
"cannot create '%.100s' instances",
type->tp_name);
 return NULL;
 }

 //通过tp_new分配空间
 //此时实例对象就已经创建完毕了,这里会返回其指针
 obj = type->tp_new(type, args, kwds);
 //类型检测,暂时不用管
 obj = _Py_CheckFunctionResult((PyObject*)type, obj, NULL);
 if (obj == NULL)
 return NULL;
 //我们说这里的参数type是类型对象,但也可以是元类
 //元类也是由PyTypeObject结构体实例化得到的
 //元类在调用的时候执行的依旧是type_call
 //所以这里是检测type指向的是不是PyType_Type
 //如果是的话,那么实例化得到的obj就不是实例对象了,而是类型对象
 //要单独检测一下
 if (type == &PyType_Type &&
 PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
 (kwds == NULL ||
(PyDict_Check(kwds) && PyDict_GET_SIZE(kwds) == 0)))
 return obj;
 //tp_new应该返回相应类型对象的实例对象(的指针)
 //但如果不是,就直接将这里的obj返回
 //此处这么做可能有点难理解,我们一会细说
 if (!PyType_IsSubtype(Py_TYPE(obj), type))
 return obj;

 //拿到obj的类型
 type = Py_TYPE(obj);
 //执行 tp_init
 //显然这个tp_init就是__init__函数
 //这与Python中类的实例化过程是一致的。
 if (type->tp_init != NULL) {
 //将tp_new返回的对象作为self,执行 tp_init
 int res = type->tp_init(obj, args, kwds);
 if (res < 0) {
 //执行失败,将引入计数减1,然后将obj设置为NULL
 assert(PyErr_Occurred());
 Py_DECREF(obj);
 obj = NULL;
 }
 else {
 assert(!PyErr_Occurred());
 }
 }
 //返回obj
 return obj;
}
Copier après la connexion

因此从上面我们可以看到关键的部分有两个:

  • 调用类型对象的 tp_new 指向的函数为实例对象申请内存

  • 调用 tp_init 指向的函数为实例对象进行初始化,也就是设置属性

所以这对应Python中的__new__和__init__,我们说__new__是为实例对象开辟一份内存,然后返回指向这片内存(对象)的指针,并且该指针会自动传递给__init__中的self。

class Girl:
 def __new__(cls, name, age):
 print("__new__方法执行啦")
 # 写法非常固定
 # 调用object.__new__(cls)就会创建Girl的实例对象
 # 因此这里的cls指的就是这里的Girl,注意:一定要返回
 # 因为__new__会将自己的返回值交给__init__中的self
 return object.__new__(cls)
 def __init__(self, name, age):
 print("__init__方法执行啦")
 self.name = name
 self.age = age
g = Girl("古明地觉", 16)
print(g.name, g.age)
"""
__new__方法执行啦
__init__方法执行啦
古明地觉 16
"""
Copier après la connexion

__new__里面的参数要和__init__里面的参数保持一致,因为我们会先执行__new__,然后解释器会将__new__的返回值和我们传递的参数组合起来一起传递给__init__。一般来说,除了cls,__new__方法的参数通常包括*args和**kwargs。

然后再回过头来看一下type_call中的这几行代码:

static PyObject *
type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
 //......
 //......
 if (!PyType_IsSubtype(Py_TYPE(obj), type))
 return obj;

 //......
 //......
}
Copier après la connexion

一般情况下,我们认为tp_new会返回该类型的实例对象,因此通常不需要编写__new__方法。如果进行重写,就需要手动返回object.__new__(cls)。可如果我们不返回,或者返回其它的话,会怎么样呢?

class Girl:
 def __new__(cls, *args, **kwargs):
 print("__new__方法执行啦")
 instance = object.__new__(cls)
 # 打印看看instance到底是个什么东东
 print("instance:", instance)
 print("type(instance):", type(instance))

 # 正确做法是将instance返回
 # 但是我们不返回, 而是返回个 123
 return 123
 def __init__(self, name, age):
 print("__init__方法执行啦")
g = Girl()
"""
__new__方法执行啦
instance:type(instance):"""
Copier après la connexion

这个句子可以重写为:“有很多需要讨论的问题,最先引起注意的是在 __init__ 中需要传入两个参数,然而我们未传入参数时并未报错。”。原因就在于这个 __init__ 压根就没有执行,因为 __new__ 返回的不是 Girl 的实例对象。

通过打印 instance,我们知道了object.__new__(cls) 返回的就是 cls 的实例对象,而这里的cls就是Girl这个类本身。如果我们不返回instance,__new__方法就会直接返回,而无法执行对应的__init__方法。我们在外部来打印一下创建的实例对象吧,看看结果:

class Girl:
 def __new__(cls, *args, **kwargs):
 return 123
 def __init__(self, name, age):
 print("__init__方法执行啦")
g = Girl()
print(g, type(g))# 123
Copier après la connexion

我们看到打印的是123,所以再次总结一些tp_new和tp_init之间的区别,当然也对应__new__和__init__的区别:

  • tp_new:为该类型对象的实例对象申请内存,在Python的__new__方法中通过object.__new__(cls)的方式申请,然后将其返回

  • tp_init:tp_new的返回值会自动传递给self,然后为self绑定相应的属性,也就是进行实例对象的初始化

但如果tp_new返回的不是对应类型的实例对象的指针,比如type_call中第一个参数接收的&PyFloat_Type,但是tp_new中返回的却是PyLongObject *,所以此时就不会执行tp_init。

以上面的代码为例,我们Girl中的__new__应该返回Girl的实例对象才对,但实际上返回了整型,因此类型不一致,所以不会执行__init__。

下面我们可以做总结了,通过类型对象去创建实例对象的整体流程如下:
  • 第一步:获取类型对象的类型对象,说白了就是元类,执行元类的 tp_call 指向的函数,即 type_call

  • 第二步:type_call 会调用该类型对象的 tp_new 指向的函数,如果 tp_new 为 NULL,那么会到 tp_base 指定的父类里面去寻找 tp_new。在新式类中,所有类都继承自 object,因此最终都会调用 object 的 __new__ 方法。然后通过访问对应类型对象中的 tp_basicsize 信息,这个信息记录着该对象的实例对象需要占用多大的内存,继而完成申请内存的操作

  • 调用type_new 创建完对象之后,就会进行实例对象的初始化,会将指向这片空间的指针交给 tp_init,但前提是 tp_new 返回的实例对象的类型要一致。

所以都说 Python 在实例化的时候会先调用 __new__ 方法,再调用 __init__ 方法,相信你应该知道原因了,因为在源码中先调用 tp_new、再调用的 tp_init。

static PyObject *
type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
 //调用__new__方法, 拿到其返回值
 obj = type->tp_new(type, args, kwds);
 if (type->tp_init != NULL) {
 //将__new__返回的实例obj,和args、kwds组合起来
 //一起传给 __init__
 //其中 obj 会传给 self,
 int res = type->tp_init(obj, args, kwds);
 //......
 return obj;
}
Copier après la connexion

所以源码层面表现出来的,和我们在 Python 层面看到的是一样的。

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!

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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Vous avez un jeu croisé?
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

PHP et Python: exemples de code et comparaison PHP et Python: exemples de code et comparaison Apr 15, 2025 am 12:07 AM

PHP et Python ont leurs propres avantages et inconvénients, et le choix dépend des besoins du projet et des préférences personnelles. 1.Php convient au développement rapide et à la maintenance des applications Web à grande échelle. 2. Python domine le domaine de la science des données et de l'apprentissage automatique.

Python vs JavaScript: communauté, bibliothèques et ressources Python vs JavaScript: communauté, bibliothèques et ressources Apr 15, 2025 am 12:16 AM

Python et JavaScript ont leurs propres avantages et inconvénients en termes de communauté, de bibliothèques et de ressources. 1) La communauté Python est amicale et adaptée aux débutants, mais les ressources de développement frontal ne sont pas aussi riches que JavaScript. 2) Python est puissant dans les bibliothèques de science des données et d'apprentissage automatique, tandis que JavaScript est meilleur dans les bibliothèques et les cadres de développement frontaux. 3) Les deux ont des ressources d'apprentissage riches, mais Python convient pour commencer par des documents officiels, tandis que JavaScript est meilleur avec MDNWEBDOCS. Le choix doit être basé sur les besoins du projet et les intérêts personnels.

Comment est la prise en charge du GPU pour Pytorch sur Centos Comment est la prise en charge du GPU pour Pytorch sur Centos Apr 14, 2025 pm 06:48 PM

Activer l'accélération du GPU Pytorch sur le système CentOS nécessite l'installation de versions CUDA, CUDNN et GPU de Pytorch. Les étapes suivantes vous guideront tout au long du processus: CUDA et CUDNN Installation détermineront la compatibilité de la version CUDA: utilisez la commande NVIDIA-SMI pour afficher la version CUDA prise en charge par votre carte graphique NVIDIA. Par exemple, votre carte graphique MX450 peut prendre en charge CUDA11.1 ou plus. Téléchargez et installez Cudatoolkit: visitez le site officiel de Nvidiacudatoolkit et téléchargez et installez la version correspondante selon la version CUDA la plus élevée prise en charge par votre carte graphique. Installez la bibliothèque CUDNN:

Explication détaillée du principe docker Explication détaillée du principe docker Apr 14, 2025 pm 11:57 PM

Docker utilise les fonctionnalités du noyau Linux pour fournir un environnement de fonctionnement d'application efficace et isolé. Son principe de travail est le suivant: 1. Le miroir est utilisé comme modèle en lecture seule, qui contient tout ce dont vous avez besoin pour exécuter l'application; 2. Le Système de fichiers Union (UnionFS) empile plusieurs systèmes de fichiers, ne stockant que les différences, l'économie d'espace et l'accélération; 3. Le démon gère les miroirs et les conteneurs, et le client les utilise pour l'interaction; 4. Les espaces de noms et les CGROUP implémentent l'isolement des conteneurs et les limitations de ressources; 5. Modes de réseau multiples prennent en charge l'interconnexion du conteneur. Ce n'est qu'en comprenant ces concepts principaux que vous pouvez mieux utiliser Docker.

Miniopen Centos Compatibilité Miniopen Centos Compatibilité Apr 14, 2025 pm 05:45 PM

Minio Object Storage: Déploiement haute performance dans le système Centos System Minio est un système de stockage d'objets distribué haute performance développé sur la base du langage Go, compatible avec Amazons3. Il prend en charge une variété de langages clients, notamment Java, Python, JavaScript et GO. Cet article introduira brièvement l'installation et la compatibilité de Minio sur les systèmes CentOS. Compatibilité de la version CentOS Minio a été vérifiée sur plusieurs versions CentOS, y compris, mais sans s'y limiter: CentOS7.9: fournit un guide d'installation complet couvrant la configuration du cluster, la préparation de l'environnement, les paramètres de fichiers de configuration, le partitionnement du disque et la mini

Comment faire fonctionner la formation distribuée de Pytorch sur CentOS Comment faire fonctionner la formation distribuée de Pytorch sur CentOS Apr 14, 2025 pm 06:36 PM

La formation distribuée par Pytorch sur le système CentOS nécessite les étapes suivantes: Installation de Pytorch: La prémisse est que Python et PIP sont installés dans le système CentOS. Selon votre version CUDA, obtenez la commande d'installation appropriée sur le site officiel de Pytorch. Pour la formation du processeur uniquement, vous pouvez utiliser la commande suivante: pipinstalltorchtorchVisionTorChaudio Si vous avez besoin d'une prise en charge du GPU, assurez-vous que la version correspondante de CUDA et CUDNN est installée et utilise la version Pytorch correspondante pour l'installation. Configuration de l'environnement distribué: la formation distribuée nécessite généralement plusieurs machines ou des GPU multiples uniques. Lieu

Comment choisir la version Pytorch sur Centos Comment choisir la version Pytorch sur Centos Apr 14, 2025 pm 06:51 PM

Lors de l'installation de Pytorch sur le système CentOS, vous devez sélectionner soigneusement la version appropriée et considérer les facteurs clés suivants: 1. Compatibilité de l'environnement du système: Système d'exploitation: Il est recommandé d'utiliser CentOS7 ou plus. CUDA et CUDNN: La version Pytorch et la version CUDA sont étroitement liées. Par exemple, Pytorch1.9.0 nécessite CUDA11.1, tandis que Pytorch2.0.1 nécessite CUDA11.3. La version CUDNN doit également correspondre à la version CUDA. Avant de sélectionner la version Pytorch, assurez-vous de confirmer que des versions compatibles CUDA et CUDNN ont été installées. Version Python: branche officielle de Pytorch

Comment mettre à jour Pytorch vers la dernière version sur Centos Comment mettre à jour Pytorch vers la dernière version sur Centos Apr 14, 2025 pm 06:15 PM

La mise à jour de Pytorch vers la dernière version sur CentOS peut suivre les étapes suivantes: Méthode 1: Mise à jour de PIP avec PIP: Assurez-vous d'abord que votre PIP est la dernière version, car les anciennes versions de PIP peuvent ne pas être en mesure d'installer correctement la dernière version de Pytorch. pipinstall-upradepip désinstalle ancienne version de Pytorch (si installé): PipuninstallTorchtorchVisiontorchaudio installation dernier

See all articles