Nous sommes en fait déjà entrés en contact avec le concept d'encapsulation auparavant. Lancer des données désordonnées dans la liste est une sorte d'encapsulation, qui est au fond. Encapsulation au niveau des données ;Emballer des segments de code couramment utilisés dans une fonction est également une sorte d'encapsulation est une encapsulation au niveau de l'instruction ;L'objet que nous voulons apprendre maintenant est aussi une idée de. encapsulation. La source de l'objet est de simuler le monde réel, en encapsulant à la fois les données et le code.
Par exemple, une tortue est un objet dans le monde réel, et elle est généralement décrite en deux parties.
(1) Description à partir de caractéristiques statiques : Par exemple, vert, a quatre pattes, a une coquille, etc. Il s'agit d'une description de l'aspect statique.
(2) Description de Comportement dynamique : Par exemple, il rampera, si vous le poursuivez, il courra, parfois il mordra, dormira, etc., tout cela vient décrit en termes de comportement.
Il en va de même pour les objets en Python, Les caractéristiques d'un objet sont appelées "propriétés" , Le comportement d'un objet est appelé "méthodes" . :
Si la tortue est écrite sous forme de code, elle sera la suivante :
class Turtle: # Python中的类名约定以大写字母开头 # 特征的描述称为属性,在代码层面看来其实就是变量 color = 'green' legs = 4 shell = True # 方法实际就是函数,通过调用这些函数来完成某些工作 def climb(self): print('向前爬') def run(self): print('向前跑') def bite(self): print('咬人') def sleep(self): print('睡觉')
Le code ci-dessus définit les caractéristiques du #🎜 🎜# objet (Attributs) et comportements (méthodes) , mais ce n'est pas un objet complet. Ceux-ci définis sont appelés classes (Class) . Vous devez utiliser une classe pour créer un objet réel. Cet objet est appelé une instance (Instance) de cette classe, également appelée Instance Objects . Par exemple, c'est comme une usine qui doit produire une série de jouets. Elle doit d'abord fabriquer un moule pour le jouet, puis le produire en série à partir de ce moule.
Créer un objet, aussi appelé instanciation d'une classe , est en réalité très simple :
# 首先要有上面那一段类的定义 tt = Turtle()
Si vous souhaitezNote : Le nom de la classe est suivi de parenthèses, ce qui revient à appeler une fonction. Ainsi, en Python, les noms de classes commencent par des lettres majuscules et les fonctions commencent par des lettres minuscules , ce qui les rend plus faciles à distinguer. De plus, l'opération d'affectation n'est pas nécessaire , mais si l'objet instance créé n'est pas affecté à une variable, l'objet ne peut pas être utilisé, car il n'y a aucune référence à cette instance, et il finira par être utilisé par Python Le mécanisme de collecte des déchets collecte automatiquement.
appeler une méthode dans un objet, utilisez l'opérateur point (.) .
Class #🎜 🎜#, Objet de classe et Objet d'instanceTrois concepts :
De ceci On peut voir dans l'exemple qu'après que
attribue une valeur à l'attribut count de l'objet instance c,équivaut à écraser l'attribut count de l'objet de classe C. Comme le montre la figure ci-dessous, s'il n'y a pas de couverture d'affectation, alors l'attribut count de l'objet de classe est référencé.
Il est à noter que les attributs définis dans la classe sont des
variables statiques, et les attributs de la classe sont lié à l'objet de classe Binding ne dépend d'aucun de ses objets d'instance. De plus,
Si le nom de l'attribut est le même que le nom de la méthode, l'attribut remplacera la méthode: #🎜 🎜#
#🎜 🎜#Afin d'éviter les conflits de noms, certaines règles courantes doivent être suivies :(1) N'essayez pas de définir toutes les fonctionnalités et méthodes imaginables dans une classe. Vous devez utiliser l'héritage. et des mécanismes de combinaison pour l’expansion. (2) Utilisez différentes parties du discours pour nommer, telles que des noms pour les noms d'attributs, des verbes pour les noms de méthodes, et utilisez la dénomination en cas de chameau.
Qu'est-ce que self
Les lecteurs attentifs découvriront que la méthode de l'objet aura un paramètre self, alors qu'est-ce que ce self ? Si vous avez été exposé au C++, vous devriez pouvoir le comprendre facilement.
Si vous n'avez jamais été exposé à un langage de programmation auparavant, alors en termes simples, si les classes sont comparées à des dessins, alors
les objets instanciés par les classes sont A maison dans laquelle vous pouvez réellement vivre. Des milliers de maisons peuvent être conçues à partir d’un seul dessin. Elles se ressemblent toutes, mais chaque maison a un propriétaire différent. Tout le monde veut trouver sa propre maison, alors self est équivalent au numéro de maison ici Avec self, vous pouvez facilement trouver votre propre maison. Le paramètre self de Python est le même. Une classe peut générer d'innombrables objets. Lorsqu'une méthode objet est appelée, l'objet transmettra sa propre référence à la méthode comme premier paramètre, alors Python saura lequel. la méthode objet doit être utilisée .
Un exemple simple :
一般面向对象的编程语言都会区分公有和私有的数据类型,像C++和Java它们使用public和private关键字用于声明数据是公有的还是私有的,但在Python中并没有类似的关键字来修饰。
默认上对象的属性和方法都是公开的,可以直接通过点操作符(.)进行访问:
为了实现类似私有变量的特征,Python内部采用了一种叫name mangling(名字改编)的技术,在Python中定义私有变量只需要在变量名或函数名前加上“_ _”两个下划线,那么这个函数或变量就会成为私有的了:
这样,在外部将变量名“隐藏”起来了,理论上如果要访问,就要从内部进行:
但是认真想一下这个技术的名字name mangling(名字改编),那就不难发现其实Python只是把双下横线开头的变量进行了改名而已。实际上,在外部使用“_类名_ _变量名”即可访问双下横线开头的私有变量了:
说明:Python目前的私有机制其实是伪私有的,Python的类是没有权限控制的,所有的变量都是可以被外部调用的。
举个例子来说明继承。例如现在有个游戏,需要对鱼类进行细分,有金鱼(Goldfish)、鲤鱼(Carp)、三文鱼(Salmon)以及鲨鱼(Shark)。那么我们能不能不要每次都从头到尾去重新定义一个新的鱼类呢?因为我们知道大多数鱼的属性和方法是相似的,如果有一种机制可以让这些相似的东西得以自动传递,那么就方便多了。这就是继承。
继承的语法很简单:
c l a s s 类 名 ( 被 继 承 的 类 ) : . . . class 类名(被继承的类): \\ \quad ... class类名(被继承的类):...
被继承的类称为基类、父类或超类;继承者称为子类,一个子类可以继承它的父类的任何属性和方法。
举个例子:
需要注意的是,如果子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性:
接下来,尝试写一下开头提到的金鱼(Goldfish)、鲤鱼(Carp)、三文鱼(Salmon)以及鲨鱼(Shark)的例子。
import random as r class Fish: def __init__(self): self.x = r.randint(0, 10) self.y = r.randint(0, 10) def move(self): # 这里主要演示类的继承机制,就不考虑检查场景边界和移动方向问题 # 假设所有的鱼都是一路向西游 self.x -= 1 print("我的位置是:", self.x, self.y) # 金鱼 class Goldfish(Fish): pass # 鲤鱼 class Carp(Fish): pass #三文鱼 class Salmon(Fish): pass # 上面三种鱼都是食物,直接继承Fish类的全部属性和方法 # 下面定义鲨鱼类,除了继承Fish类的属性和方法,还要添加一个吃的方法 class Shark(Fish): def __init__(self): self.hungry = True def eat(self): if self.hungry: print("吃掉你!") self.hungry = False else: print("太饱了,吃不下了~")
首先运行这段代码,然后进行测试:
同样是继承于Fish类,为什么金鱼(goldfish)可以移动,而鲨鱼(shark)一移动就报错呢?
可以看到报错提示为:Shark对象没有x属性,这是因为在Shark类中,重写了_ _init_ _()方法,但新的_ _init_ _()方法里面没有初始化鲨鱼的x坐标和y坐标,因此调用move()方法就会出错。
那么解决这个问题,只要在鲨鱼类中重写_ _init_ _()方法的时候先调用基类Fish的_ _init_ _()方法。
下面介绍两种可以实现的技术:
(1)调用未绑定的父类方法
(2)使用super函数
什么是调用未绑定的父类方法?举个例子:
修改之后,再运行下发现鲨鱼也可以成功移动了:
这里需要注意的是,这个self并不是父类Fish的实例对象,而是子类Shark的实例对象。所以这里说的未绑定是指并不需要绑定父类的实例对象,使用子类的实例对象代替即可。
La super fonction peut nous aiderà trouver automatiquement la méthode de classe de base, et également à transmettre le paramètre self pour nous, nous n'avons donc pas besoin de faire ces choses :
Après l'exécution, nous obtenons le même résultat :
Héritage multipleDe plus, Python prend également en chargeL'héritage multiple, c'est-à-dire que vous pouvez hériter des propriétés et des méthodes de plusieurs classes parents en même temps :
c l a s s nom de classe (classe parent 1, classe parent 2, classe parent 3, . . . ) : . quad ... classe nom de classe (classe parent 1, classe parent 2, classe parent 3,...):...
Par exemple :
Il s'agit de la syntaxe de base de l'héritage multiple, mais L'héritage multiple peut facilement conduire à une confusion dans le code. Ainsi, lorsque vous n'êtes pas sûr de devoir réellement utiliser l'héritage multiple, essayez d'éviter de l'utiliser, car des BUGs imprévus peuvent parfois survenir. CompositionNous avons déjà appris le concept d'héritage et mentionné l'héritage multiple, mais si nous avons maintenant des tortues et des poissons, nous devons maintenant définir une classe appelée piscine, et il doit y avoir des tortues et des poissons dans la piscine . Il semble étrange d'utiliser l'héritage multiple, car la piscine, la tortue et les poissons sont des espèces différentes, alors comment les combiner dans une classe de piscine ?En fait, c'est très simple en Python. Il suffit de
insérer les classes requises et d'instancier C'est ce qu'on appelle une combinaison :
Exécutez d'abord le code ci-dessus, puis testez :
. Construction et destructionLes objets Python ont de nombreuses méthodes magiques. Si votre objet implémente l'une de ces méthodes, alors cette méthode sera appelée par Python dans des circonstances particulières, et tout cela se produit automatiquement.
_ _init_ _(self[, …]) constructeur La méthode _ _init_ _() est généralement appelée le constructeur. Tant qu'un objet est instancié,cette méthode sera automatiquement appelée lors de la création de l'objet. . Les paramètres peuvent être transmis lors de l'instanciation d'un objet. Ces paramètres seront automatiquement transmis à la méthode _ _init_ _(). Vous pouvez personnaliser l'opération d'initialisation de l'objet en remplaçant cette méthode. Par exemple :
Certains lecteurs peuvent demander, parfois la méthode _ _init_ _() est écrite dans la définition de la classe, mais parfois non, pourquoi ? Regardez l'exemple suivant :
Ce qu'il faut noter ici, c'est que la valeur de retour de la méthode _ _init_ _() doit être None et ne peut pas être autre
:
Donc, est généralement utilisé lorsque l'initialisation est requise Réécrivez simplement la méthode _ _init_ _()
. Cette méthode _ _init_ _() n'est donc pas la première méthode appelée lors de l'instanciation d'un objet._ méthode _new_ _(cls[, …]) _ La méthode _new_ _() est la première méthode appelée lorsqu'un objet est instancié. Différent des autres méthodes, son premier paramètre n'est pas self mais la classe (cls), et les autres paramètres seront passés directement à la méthode _ _init_ _(). La méthode
, généralement l'objet instancié par la classe cls. Bien sûr, vous pouvez également renvoyer d'autres objets. La méthode _ _new_ _() est rarement réécrite. Généralement, Python peut être exécuté avec le schéma par défaut. Mais il existe une situation où vous devez remplacer cette méthode, c'est-à-dire que
lorsque vous héritez d'un type immuable, ses caractéristiques deviennent particulièrement importantes.
_ _del_ _(self) destructeur méthode Si les méthodes _ _init_ _() et _ _new_ _() sont les constructeurs d'objets, alors Python fournit également un destructeur appelé méthode _ _del_ _(). Lorsque l'objet est sur le point d'être détruit, cette méthode sera appelée
. Cependant, il convient de noter que del x n'équivaut pas à appeler automatiquement x._ _del_ _() La méthode _ _del_ _() est appelée lorsque le mécanisme de garbage collection recycle cet objet.Par exemple :
Le concept de reliure a déjà été mentionné, alors qu'est-ce que la reliure exactement ? Python exige strictement que les méthodes aient une instance avant de pouvoir être appelées. Cette restriction est en fait ce qu'on appelle le concept de liaison de Python.
Quelqu'un peut essayer ceci et constater qu'il peut également être appelé :
Cependant , Il y aura un problème avec ça, c'est-à-dire L'objet instancié selon la classe ne peut pas du tout appeler les fonctions à l'intérieur :
En fait, c'est grâce au mécanisme de liaison de Python que l'objet bb est automatiquement transmis comme premier paramètre, donc TypeError se produit.
Regardez un autre exemple :
_ _dict_ _L'attribut est composé d'un dictionnaire , il n'y a que les attributs des objets d'instance dans le dictionnaire, et les attributs de classe et les attributs spéciaux ne sont pas affichés. La clé représente le nom de l'attribut , et le #🎜🎜. # La valeur représente l'attribut correspondant. Valeur des données .
Maintenant, l'objet instance dd a deux nouveaux attributs, et ces deux attributs n'appartiennent qu'à l'objet instance :#🎜🎜 ## 🎜🎜#
Pourquoi ça ? En fait, cela est entièrement dû au paramètre self : lorsque l'objet instance dd appelle la méthode setXY, le premier paramètre qu'il transmet est dd
, alors self.x = 4, self.y = 5 C'est équivalent à dd.x = 4, dd.y = 5, vous ne pouvez donc pas voir x et y dans l'objet instance ni même dans l'objet classe, carces deux attributs n'appartiennent qu'à l'objet instance dd # 🎜🎜#. Si l'instance de classe est supprimée, l'objet d'instance dd peut-il toujours appeler la méthode printXY ? La réponse est oui :
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!