ホームページ >バックエンド開発 >Python チュートリアル >オブジェクト指向のPythonコードの詳細を説明する

オブジェクト指向のPythonコードの詳細を説明する

Y2J
Y2Jオリジナル
2017-05-10 11:38:501249ブラウズ

Python は最初からオブジェクト指向言語であり、そのため、Python でクラスやオブジェクトを作成するのは簡単です。 Pythonのオブジェクト指向プログラミングについては以下の記事で詳しく紹介していますので、困っている方はぜひ参考にしてみてください。

はじめに

これまでオブジェクト指向プログラミング言語に触れたことがない場合は、まずオブジェクト指向言語のいくつかの基本的な機能を理解し、オブジェクト指向の基本的な概念を形成する必要があるかもしれませんこれは、Python オブジェクト指向プログラミングをより簡単に学習するのに役立ちます。

次に、Python オブジェクト指向プログラミングについて学びましょう。

クラスとインスタンス

クラスはオブジェクトの定義であり、インスタンスはクラスで定義されたオブジェクトの固有の情報を格納する「実際のオブジェクト」です。

クラス、プロパティとメソッド命名規則

クラス名は通常、大文字で始まります。これは標準的な規則であり、特にインスタンス化中 (function 呼び出しのように見える場合もあります) にクラスを識別するのに役立ちます。また、データ属性 (変数 または 定数) はデータ値の名前のように聞こえる必要があり、メソッド名は対応するオブジェクトまたは値の 動作 を示す必要があります。

もう 1 つの表現方法は、データ値は名前として名詞を使用し、メソッドは述語 (動詞とオブジェクト) を使用する必要があります。データ項目は操作対象のオブジェクトであり、メソッドはプログラマがオブジェクトに対してどのような操作を実行したいかを示す必要があります。

定義されたクラスでは、大まかにこのガイドラインに従い、データ値は「name」、「phone」、「email」のようになり、動作は「updatePhone」、「updateEmail」のようになります。これは、「mixedCase」または「camelCase」と呼ばれることがよくあります。 Python 仕様では、「update_phone」、「update_email」など、アンダースコアを含むラクダ表記を使用することが推奨されています。クラスの名前も慎重に付ける必要があります。「AddrBookEntry」、「RepairShop」などの名前が適切です。

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

新しいスタイルのクラスと古いスタイルのクラス

新しいスタイルのクラスと従来のクラス宣言の最大の違いは、すべての新しいスタイルのクラスが少なくとも 1 つの親クラスを継承する必要があることです。継承するクラスがない場合は、オブジェクトクラスを継承できます。オブジェクトは「すべてのクラスの母」であり、すべてのクラス継承構造の最上位に位置します。オブジェクトの直接的または間接的なサブクラス化がない場合は、クラシック クラスが定義されます。つまり、親クラスが指定されていない場合、またはサブクラス化される基本クラスに親クラスがない場合は、クラシック クラスが作成されます。

Python3 で定義されたクラスは、デフォルトでは新しいスタイルのクラスです。Python2 で新しいスタイルのクラスを定義するには、オブジェクトを継承するか、新しいスタイルのクラスを継承する必要があります。

self 変数

このクラスのメソッドには、通常の関数との特別な違いが 1 つだけあります。つまり、追加の最初のパラメーター名が必要ですが、呼び出し時にこのパラメーターに値を割り当てる必要はありません。このメソッドでは、Python がこの値を提供します。この特定の変数はオブジェクト自体を参照し、慣例によりその名前は self です。このパラメータには任意の名前を付けることができますが、self という名前を使用することを強くお勧めします。他の名前は非推奨です。

init() メソッド

init() 类似于类构造器,但实际上并不是一个构造器。Python 创建实例后,在实例化过程中,调用 init() メソッドでは、クラスがインスタンス化されるときに、初期値の設定や予備的な診断コードの実行などの追加の動作を定義できます。これは主にインスタンスの作成時に行われます。 、インスタンス化呼び出しは、特定のタスクまたは設定を実行するためにこのインスタンスを返します。

バインドされたメソッドとアンバインドされたメソッド

Python では、クラスにアクセスするメソッドには、インスタンスを通じて直接アクセスすることも、クラスを通じて直接アクセスすることもできます。ただし、Python では、インスタンスなしではメソッドを呼び出すことができないことが厳密に要求されます。この制限は Python でバインディングと呼ばれるもので、メソッドを直接呼び出すにはメソッドを (インスタンスに) バインドする必要があります。バインドされていないメソッドを呼び出すこともできますが、呼び出しが成功することを保証するにはインスタンス オブジェクトを明示的に指定する必要があります。ただし、バインドされているかどうかに関係なく、メソッドは、ほとんどの場合インスタンスを通じて呼び出されますが、メソッドが存在するクラスの固有のプロパティです。 Python のクラス メソッドもオブジェクトです。クラスを通じて直接アクセスされるメソッドは「非バインド メソッド」と呼ばれ、インスタンスを通じてアクセスされるメソッドは「バインド メソッド」と呼ばれることは単純に理解できます:

1. アンバウンド クラス メソッド: なし self

通过类来引用方法返回一个未绑定方法对象。要调用它,你必须显示地提供一个实例作为第一个参数。

2. 绑定的实例方法:有 self

通过实例访问方法返回一个绑定的方法对象。Python 自动地给方法绑定一个实例,所以我们调用它时不用再传一个实例参数。

示例:

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

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

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

类属性与实例属性

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

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

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

私有化

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)
['_TestObjfoo', '_TestObjhar', '_TestObjwar', '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: &#39;TestObj&#39; object has no attribute &#39;war&#39;
>>> t.har
Traceback (most recent call last):
 File "<input>", line 1, in <module>
 t.har
AttributeError: &#39;TestObj&#39; object has no attribute &#39;har&#39;
>>> t.foo()
Traceback (most recent call last):
 File "<input>", line 1, in <module>
 t.foo()
AttributeError: &#39;TestObj&#39; object has no attribute &#39;foo&#39;
>>> t._TestObjwar
&#39;world&#39;
>>> t._TestObjhar
&#39;hello&#39;
>>> t._TestObjfoo()
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
{&#39;age&#39;: 25, &#39;name&#39;: &#39;huoty&#39;}

字典位于实例的“心脏” 。 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&#39;t think so"
Traceback (most recent call last):
 File "<input>", line 1, in <module>
AttributeError: &#39;SlotedClass&#39; object has no attribute &#39;goo&#39;


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

总结

【相关推荐】

1. Python免费视频教程

2. python遇见数据采集视频

3. Python学习手册

以上がオブジェクト指向のPythonコードの詳細を説明するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。