この記事の例では、Python オブジェクトとオブジェクト指向テクノロジーについて説明します。以下のように、参考としてみんなと共有してください:
1 まず例を見てみましょう。この章では、このサンプル プログラムについて説明します:
ファイル: fileinfo.py:
"""Framework for getting filetype-specific metadata. Instantiate appropriate class with filename. Returned object acts like a dictionary, with key-value pairs for each piece of metadata. import fileinfo info = fileinfo.MP3FileInfo("/music/ap/mahadeva.mp3") print "\n".join(["%s=%s" % (k, v) for k, v in info.items()]) Or use listDirectory function to get info on all files in a directory. for info in fileinfo.listDirectory("/music/ap/", [".mp3"]): ... Framework can be extended by adding classes for particular file types, e.g. HTMLFileInfo, MPGFileInfo, DOCFileInfo. Each class is completely responsible for parsing its files appropriately; see MP3FileInfo for example. """ import os import sys from UserDict import UserDict def stripnulls(data): "strip whitespace and nulls" return data.replace("{post.content}", "").strip() class FileInfo(UserDict): "store file metadata" def __init__(self, filename=None): UserDict.__init__(self) self["name"] = filename class MP3FileInfo(FileInfo): "store ID3v1.0 MP3 tags" tagDataMap = {"title" : ( 3, 33, stripnulls), "artist" : ( 33, 63, stripnulls), "album" : ( 63, 93, stripnulls), "year" : ( 93, 97, stripnulls), "comment" : ( 97, 126, stripnulls), "genre" : (127, 128, ord)} def __parse(self, filename): "parse ID3v1.0 tags from MP3 file" self.clear() try: fsock = open(filename, "rb", 0) try: fsock.seek(-128, 2) tagdata = fsock.read(128) finally: fsock.close() if tagdata[:3] == "TAG": for tag, (start, end, parseFunc) in self.tagDataMap.items(): self[tag] = parseFunc(tagdata[start:end]) except IOError: pass def __setitem__(self, key, item): if key == "name" and item: self.__parse(item) FileInfo.__setitem__(self, key, item) def listDirectory(directory, fileExtList): "get list of file info objects for files of particular extensions" fileList = [os.path.normcase(f) for f in os.listdir(directory)] fileList = [os.path.join(directory, f) for f in fileList if os.path.splitext(f)[1] in fileExtList] def getFileInfoClass(filename, module=sys.modules[FileInfo.__module__]): "get file info class from filename extension" subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:] return hasattr(module, subclass) and getattr(module, subclass) or FileInfo return [getFileInfoClass(f)(f) for f in fileList] if __name__ == "__main__": for info in listDirectory("/music/_singles/", [".mp3"]): print "\n".join(["%s=%s" % (k, v) for k, v in info.items()]) print
2 モジュールインポートから使用します。モジュールをインポートするには
前に学習したインポートモジュールは次の構文を使用します:
import module name
このように、このモジュール内のものを使用する必要がある場合は、モジュール名と using を使用する必要があります。名前を直接指定するとエラーになりますので、 print:
>>> import types >>> types.FunctionType <type 'function'> >>> FunctionType
次に、モジュールに名前をインポートするための別の構文を見てみましょう:
from module name import name
または
from module name import *
たとえば:
Traceback (most recent call last): File "<interactive input>", line 1, in <module> NameError: name 'FunctionType' is not defined
インポートされた名前は、モジュール名なしで直接使用できます。 例:
>>> from types import FunctionType
3 クラス定義
クラスを定義するための構文:
class クラス名:
pass または class クラス名 (基本クラスのリスト): pass
は、何もしないことを意味します。例:
>>> FunctionType <type 'function'>
class A(B) : " this is class A. "
__init__
Python では、派生クラスを構築するときに、基本クラスのコンストラクターが「自動的に」呼び出されないことに注意してください。必要に応じて、すべてのクラス メソッドを明示的に書き出す必要があります。
最初のパラメーターはすべて使用されます。このポインタを受け取るには、このパラメータの通常の名前は self です。ただし、上記のようなコンストラクタでは、このパラメータは _init() である必要があります。
4 クラスのインスタンス化
クラスのインスタンス化は、他の言語のような関数として呼び出すだけです。
クラス名 (パラメータ リスト)
__init__ の最初のパラメータ self をパラメータ リストで指定する必要はありません。
例:
a = A()
クラスまたはクラスのインスタンスを渡すことができます。ドキュメントを参照してください。これは、そのクラスの __doc__ 属性を通じて行われます。例:
class A(B) : "this is class A. " def __init__ (self): B.__init__(self)
これは、そのクラスのインスタンスを取得することもできます。例:
>>> A.__doc__ 'this is class A. ' >>> a.__doc__ 'this is class A. '
クラスのインスタンスを作成した後は、ガベージ コレクションにより、参照カウントに基づいて未使用のオブジェクトが自動的に破棄されます。
Python では、クラスのデータ メンバーに対する特別な宣言ステートメントはありません。そして、代入中に「突然生成」されます。例:
>>> a.__class__ <class __main__.A at 0x011394B0>
このとき、データは自動的にクラス A のメンバーになります。
その後、クラスの定義で次のようにする必要があります。クラスまたはメンバー メソッドでメンバー変数を使用します。これらは self の名前で修飾する必要があります。したがって、データ メンバーは通常、メソッド内で self の名前に値を代入するだけで生成されます。 __init__ メソッドでは、すべてのデータ属性は次のとおりです。
Python は関数のオーバーロードをサポートしていません
実際、コード ブロックに 1 つの文しかない場合は、それが可能です。改行せずにコロンの直後に配置します。
6 特別なクラスのメソッド
は、クラス内で特別なメソッドを定義した後、それらを明示的に呼び出す必要はありません。代わりに、Python がそれらを自動的に呼び出します。特定の時間に。
データ項目を取得および設定します。
これには、クラスで __getitem__ メソッドと __setitem__ メソッドを定義する必要があります。
例:
class A : def __init__(self) : self.data = []
ここでの a[1] は、__getitem__ メソッドを呼び出します。は a.__getitem__(1) と等しいです。
__getitem__ メソッドに似ているのは __setitem__
たとえば、上記のクラス A で定義されています:
>>> class A: ... def __init__(self): ... self.li = range(5) ... def __getitem__(self, i): ... return self.li[-i] ... >>> a = A() >>> print a[1]
次に、このメソッドを次のように呼び出します:
a[1] = 0 a.__setitem__ (1, 0) を呼び出すのと同じです
7 高度な特殊クラスのメソッド
は __getitem__ __setitem__ に似ています。次のような特殊な関数もあります。このオブジェクトの文字列表現を表すために使用されます。たとえば、
def __setitem__(self, key, item): self.li[key] = item
この repr() は、実際にはどのオブジェクトにも適用できます。インタラクティブなウィンドウで、変数名を入力して Enter を押すだけです。 repr を使用して変数の値を表示します。
def __repr__(self): return repr(self.li)
2 つのインスタンス self と ) が
repr(a)
オブジェクトの長さを返すために使用されます。len(object)を使用するときに呼び出されます。
必要な論理長の値を指定するために使用します。def __cmp__(self, x): if isinstance(x, A): return cmp(self.li, x.li)
a = A() b = A() a == b
def __len__(self): return len(self.li)
Python には「プライベート」という概念もあります。
プライベート関数はそのモジュールの外部から呼び出すことはできません。
プライベート プロパティはクラスの外部からアクセスすることはできません。 Python にはプライベートとパブリックの 2 種類しかありません。パブリックとプライベートの区別は、関数、クラスのメソッド、およびクラスの属性によって異なります。 (ただし、プライベートのものの名前は __ で始まります)。前述したプライベートなもの (__getitem__ など) はプライベートではありません)。