Heim  >  Artikel  >  Backend-Entwicklung  >  Zusammenfassung der Wissenspunkte zur objektorientierten Python-Programmierung

Zusammenfassung der Wissenspunkte zur objektorientierten Python-Programmierung

高洛峰
高洛峰Original
2017-02-18 10:14:221317Durchsuche

Python war von Anfang an eine objektorientierte Sprache. Aus diesem Grund ist es einfach, Klassen und Objekte in Python zu erstellen. Der folgende Artikel stellt Ihnen die Wissenspunkte zur objektorientierten Programmierung in Python im Detail vor. Lassen Sie uns gemeinsam einen Blick darauf werfen.

Vorwort

Wenn Sie noch nie mit objektorientierten Programmiersprachen in Berührung gekommen sind, müssen Sie möglicherweise zunächst einige Grundfunktionen objektorientierter Sprachen verstehen und ein Basisobjekt bilden -orientierte Programmiersprache im Kopf, die Ihnen das Erlernen der objektorientierten Programmierung in Python erleichtert.

Als nächstes lernen wir etwas über objektorientierte Programmierung in Python.

Klassen und Instanzen

Eine Klasse ist die Definition eines Objekts, und eine Instanz ist das „echte Objekt“, das die spezifischen Informationen des in der Klasse definierten Objekts speichert.

Konventionen zur Benennung von Klassen, Attributen und Methoden

Klassennamen beginnen normalerweise mit einem Großbuchstaben. Dies ist eine Standardkonvention und kann Ihnen dabei helfen, Klassen zu identifizieren, insbesondere während der Instanziierung (die manchmal wie Funktionsaufrufe aussieht). Außerdem sollten Datenattribute (Variablen oder Konstanten) wie die Namen von Datenwerten klingen und Methodennamen sollten das Verhalten des entsprechenden Objekts oder Werts angeben.

Eine andere Möglichkeit, es auszudrücken, ist: Datenwerte sollten Substantive als Namen verwenden und Methoden sollten Prädikate (Verben plus Objekte) verwenden. Das Datenelement ist das Objekt der Operation, und die Methode sollte angeben, welche Operation der Programmierer für das Objekt ausführen möchte.

Befolgen Sie in der definierten Klasse grob diese Richtlinie, mit Datenwerten wie „Name“, „Telefon“ und „E-Mail“ und Verhaltensweisen wie „updatePhone“ und „updateEmail“. Dies wird oft als „mixedCase“ oder „camelCase“ bezeichnet. Die Python-Spezifikation empfiehlt die Verwendung der Kamelnotation mit Unterstrichen, zum Beispiel „update_phone“, „update_email“. Klassen sollten auch sorgfältig benannt werden, z. B. „AddrBookEntry“, „RepairShop“ usw. sind gute Namen.

class AddrBookEntry(object):

 def __init__(self, name, phone, email):
 self.name = name
 self.phone = phone
 self.email = email

 def update_phone(self, phone):
 self.phone = phone

 def update_email(self. email):
 self.email = email

Klassen im neuen Stil und Klassen im alten Stil

Der größte Unterschied zwischen Klassen im neuen Stil und klassischen Klassendeklarationen besteht darin Alle Klassen neuen Stils müssen mindestens eine übergeordnete Klasse erben. Wenn es keine Klasse gibt, von der geerbt werden kann, kann die Objektklasse geerbt werden. Das Objekt ist die „Mutter aller Klassen“ und steht an der Spitze aller Klassenvererbungsstrukturen. Wenn es keine direkte oder indirekte Unterklasse eines Objekts gibt, wird eine klassische Klasse definiert. Das heißt, wenn keine übergeordnete Klasse angegeben ist oder die Basisklasse, deren Unterklasse zugrunde liegt, keine übergeordnete Klasse hat, wird eine klassische Klasse erstellt.

In Python3 definierte Klassen sind standardmäßig Klassen neuen Stils. Um eine Klasse neuen Stils in Python2 zu definieren, müssen Sie ein Objekt erben oder eine Klasse neuen Stils erben.

Selbstvariable

Die Methoden der Klasse haben nur einen besonderen Unterschied zu gewöhnlichen Funktionen, das heißt, sie müssen einen zusätzlichen ersten Parameternamen haben, aber Sie müssen dies beim Aufruf nicht tun Weisen Sie diese Methode zu und Python stellt diesen Wert bereit. Diese spezielle Variable bezieht sich auf das Objekt selbst und heißt laut Konvention „self“. Obwohl Sie diesem Parameter einen beliebigen Namen geben können, wird dringend empfohlen, den Namen self zu verwenden. Andere Namen sind veraltet.

__init__()-Methode

__init__() ähnelt einem Klassenkonstruktor, ist aber eigentlich kein Konstruktor. Nachdem Python eine Instanz erstellt hat, ruft es während des Instanziierungsprozesses die Methode __init__() auf. Wenn eine Klasse instanziiert wird, können Sie zusätzliche Verhaltensweisen definieren, z. B. das Festlegen von Anfangswerten oder das Ausführen eines vorläufigen Diagnosecodes Wenn eine Instanz erstellt wird, führt der Instanziierungsaufruf bestimmte Aufgaben oder Einstellungen aus, bevor die Instanz zurückgegeben wird.

Gebundene und ungebundene Methoden

In Python kann auf Methoden für den Zugriff auf eine Klasse direkt über Instanzen oder direkt über Klassen zugegriffen werden. Allerdings verlangt Python strikt, dass Methoden nicht ohne Instanz aufgerufen werden können. Diese Einschränkung wird in Python als Bindung beschrieben, wobei eine Methode (an eine Instanz) gebunden sein muss, um direkt aufgerufen zu werden. Ungebundene Methoden können aufgerufen werden, das Instanzobjekt muss jedoch explizit angegeben werden, um sicherzustellen, dass der Aufruf erfolgreich ist. Unabhängig davon, ob sie gebunden sind oder nicht, sind Methoden inhärente Eigenschaften der Klasse, in der sie sich befinden, auch wenn sie fast immer über Instanzen aufgerufen werden. Klassenmethoden in Python sind ebenfalls Objekte. Es kann einfach verstanden werden, dass Methoden, auf die direkt über Klassen zugegriffen wird, „ungebundene Methoden“ genannt werden, während Methoden, auf die über Instanzen zugegriffen wird, „gebundene Methoden“ genannt werden:

1. Ungebundene Klassen Methode: Kein Selbst

Der Verweis auf eine Methode über eine Klasse gibt ein ungebundenes Methodenobjekt zurück. Um es aufzurufen, müssen Sie explizit eine Instanz als erstes Argument angeben.

2. Gebundene Instanzmethoden: Es gibt self

, das über die Instanzzugriffsmethode ein gebundenes Methodenobjekt zurückgibt. Python bindet automatisch eine Instanz an die Methode, sodass wir beim Aufruf keinen Instanzparameter übergeben müssen.

Beispiel:

class Test:
 def func(self, message):
 print message

object1 = Test()
x = object1.func
x("绑定方法对象,实例是隐藏的")

t = Test.func
t(object1, "未绑定方法对象,需要传递一个实例")
# t("未绑定方法对象,需要传递一个实例") # 错误的调用

Klassenattribute und Instanzattribute

类属性仅是与类相关的数据值,和实例属性不同,类属性和实例无关。这些值像静态成员那样被引用,即使在多次实例化中调用类,它们的值都保持不变。不管如何,静态成员不会因为实例而改变它们的值,除非实例中显式改变它们的值。 实例属性与类属性的比较,类似于自动变量和静态变量,但这只是笼统的类推。在你对自动变量和静态变量还不是很熟的情况下,不要深究这些。

类和实例都是名字空间。类是类属性的名字空间,实例则是实例属性的。

可采用类来访问类属性,如果实例没有同名的属性的话,也可以用实例来访问。

私有化

Python并不直接支持私有方式,而要靠程序员自己把握在外部进行特性修改的时机。

为了让方法或者特性变为私有(从外部无法访问),只要在它的名字前面加上双下划线即可。由双下划线 __ 开始的属性在运行时被“混淆”,所以直接访问是不允许的。

实际上,在 Python 带有双下划线的属性或方法并非正真意义上的私有,它们仍然可以被访问。在类的内部定义中,所有以双下划线开始的名字都被“翻译”成前面加上单下划线和类名的形式:

>>> class TestObj(object):
... __war = "world"
... 
... def __init__(self):
...  self.__har = "hello"
...  
... def __foo(self):
...  print(self.__har + self.__war)
...  
... 
... 
>>> t = TestObj()
>>> dir(t)
['_TestObj__foo', '_TestObj__har', '_TestObj__war', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getat
tribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__
', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>> t.__war
Traceback (most recent call last):
 File "<input>", line 1, in <module>
 t.__war
AttributeError: 'TestObj' object has no attribute '__war'
>>> t.__har
Traceback (most recent call last):
 File "<input>", line 1, in <module>
 t.__har
AttributeError: 'TestObj' object has no attribute '__har'
>>> t.foo()
Traceback (most recent call last):
 File "<input>", line 1, in <module>
 t.foo()
AttributeError: 'TestObj' object has no attribute 'foo'
>>> t._TestObj__war
'world'
>>> t._TestObj__har
'hello'
>>> t._TestObj__foo()
helloworld

__slots__ 类属性

正常情况下,当我们定义了一个 class,创建了一个 class 的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性。在 Python 中默认用字典来存储实例的属性。

示例:

>>> class A():
... pass
... 
>>> a = A()
>>> a.name = "huoty"
>>> a.age = 25
>>> print a.name
huoty
>>> print a.age
25
>>> a.__dict__
{'age': 25, 'name': 'huoty'}

字典位于实例的“心脏” 。 __dict__属性跟踪所有实例属性。举例来说,你有一个实例 inst,它有一个属性 foo,那使用 inst.foo 来访问它与使用 inst.__dict__['foo'] 来访问是一致的。

字典会占据大量内存,如果你有一个属性数量很少的类,但有很多实例,那么正好是这种情况。为内存上的考虑,可以使用 __slots__ 属性来替代 __dict__ 。

, __slots__ 是新式类的特性。基本上, __slots__ 是一个类变量,由一序列对象组成,由所有合法标识构成的实例属性的集合来表示。它可以是一个列表,元组或可迭代对象。也可以是标识实例能拥有的唯一的属性的简单字符串。任何试图创建一个其名不在 __slots__ 中的名字的实例属性都将导致 AttributeError 异常:

>>> class SlotedClass(object):
... __slots__ = ("foo", "bar")
... 
... 
>>> c = SlotedClass()
>>> c.foo = 42
>>> c.bar = "hello"
>>> c.goo = "don't think so"
Traceback (most recent call last):
 File "<input>", line 1, in <module>
AttributeError: 'SlotedClass' object has no attribute 'goo'

这种特性的主要目的是节约内存。其副作用是某种类型的"安全",它能防止用户随心所欲的动态增加实例属性。带 __slots__ 属性的类定义不会存在 __dict__ 了(除非你在 __slots__ 中增加 __dict__ 元素)。


更多关于Python面向对象编程的知识点总结相关文章请关注PHP中文网!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn