Python でシングルトンを実装する最良の方法
シングルトン設計パターンの長所と短所はこの記事の焦点ではありませんが、この記事では、シングルトン設計パターンの利点と欠点について説明します。可能な限り最善の方法で Python にシングルトンを実装するには、このパターンを Python 的な方法で実装します。ここで、「最も Python 的」とは、「最小の驚きの原則」に従うことを意味します。
実装方法
方法 1: デコレータ
def singleton(class_): instances = {} def getinstance(*args, **kwargs): if class_ not in instances: instances[class_] = class_(*args, **kwargs) return instances[class_] return getinstance @singleton class MyClass(BaseClass): pass
利点:
- デコレータは追加のセックスを持ち、多重継承よりも直感的です。
欠点:
- MyClass() を使用して作成されたオブジェクトは実際のシングルトン オブジェクトですが、MyClass 自体はクラスではなく関数です。したがって、クラスメソッドを呼び出すことはできません。
方法 2: 基本クラス
class Singleton(object): _instance = None def __new__(class_, *args, **kwargs): if not isinstance(class_._instance, class_): class_._instance = object.__new__(class_, *args, **kwargs) return class_._instance class MyClass(Singleton, BaseClass): pass
利点:
- これは実際のクラスです。
欠点:
- 多重継承、不快。 2 番目の基本クラスから継承する場合、__new__ がオーバーライドされる可能性があります。
方法 3: メタクラス
class Singleton(type): _instances = {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) return cls._instances[cls] # Python2 class MyClass(BaseClass): __metaclass__ = Singleton # Python3 class MyClass(BaseClass, metaclass=Singleton): pass
利点:
- これは実際のクラスです。
- 継承は自動的にカバーされます。
- __metaclass__ を正しく使用してください (そして、それを理解させてください)。
デメリット:
- デメリットはありません。
方法 4: 同じ名前のクラスのデコレータを返す
def singleton(class_): class class_w(class_): _instance = None def __new__(class_, *args, **kwargs): if class_w._instance is None: class_w._instance = super(class_w, class_).__new__(class_, *args, **kwargs) class_w._instance._sealed = False return class_w._instance def __init__(self, *args, **kwargs): if self._sealed: return super(class_w, self).__init__(*args, **kwargs) self._sealed = True class_w.__name__ = class_.__name__ return class_w @singleton class MyClass(BaseClass): pass
利点:
- です。本当のクラス。
- 継承は自動的にカバーされます。
短所:
- シングルトンにしたいクラスごとに 2 つのクラスを作成するとオーバーヘッドが発生しますか?私の場合はこれでうまくいきましたが、拡張できないのではないかと心配しています。
- _sealed 属性の目的は何ですか?
- 基底クラス内で同じ名前のメソッドを呼び出すのに super() を使用することは再帰的になるためできません。これは、__new__ をカスタマイズしたり、__init__ の呼び出しを必要とするクラスをサブクラス化したりできないことを意味します。
方法 5: モジュール
シングルトン モジュール singleton.py。
長所:
- 複雑よりもシンプルの方が優れています。
欠点:
- インスタンス化は遅延されません。
推奨方法
方法 2 を使用することをお勧めしますが、基本クラスの代わりにメタクラスを使用することをお勧めします。以下に実装例を示します:
class Singleton(type): _instances = {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) return cls._instances[cls] class Logger(object): __metaclass__ = Singleton
または Python3 の場合:
class Logger(metaclass=Singleton): pass
クラスが呼び出されるたびに __init__ を実行したい場合は、次のコードを Singleton.__call__ In に追加します。 if ステートメント:
def singleton(class_): instances = {} def getinstance(*args, **kwargs): if class_ not in instances: instances[class_] = class_(*args, **kwargs) return instances[class_] return getinstance @singleton class MyClass(BaseClass): pass
メタクラスの役割
メタクラスはクラスのクラス、つまり、クラスはそのメタクラスのインスタンスです。 Python のオブジェクトのメタクラスは、type(obj) によって見つけることができます。通常の新しいクラスは type 型です。 Logger の (唯一の) インスタンスがクラス 'your_module.Logger' であるのと同様に、上記の Logger はクラス 'your_module.Singleton' になります。 Logger() を使用してロガーが呼び出されるとき、Python はまずロガーのメタクラス Singleton に何をすべきかを尋ね、プリエンプティブなインスタンスの作成を可能にします。このプロセスは、Python が __getattr__ を呼び出してその属性をどのように処理するかをクラスに問い合わせる方法と似ており、myclass.attribute を実行してその属性を参照します。
メタクラスは基本的に、呼び出しクラスの意味とその意味の実装方法を決定します。たとえば、メタクラスを使用して Python で C スタイルの構造を再作成する http://code.activestate.com/recipes/498149/ を参照してください。ディスカッション スレッド [メタクラスの具体的な使用例は何ですか? ](https://codereview.stackexchange.com/questions/82786/what-are-some-concrete-use-cases-for-metaclasses) では、一般的に宣言型プログラミング、特にで使用される ORM に関連するいくつかの例も提供しています。 。
この場合、メソッド 2 を使用し、サブクラスで __new__ メソッドが定義されている場合、SubClassOfSingleton() が呼び出されるたびにこのメソッドが実行されます。これは、メソッドを呼び出す責任があるためです。保存されたインスタンスを返します。メタクラスの場合、一意のインスタンスの作成時に一度だけ実行されます。呼び出しクラスの定義をカスタマイズする必要があります。呼び出しクラスの定義は、その型によって決まります。
一般に、メタクラスを使用してシングルトンを実装することは理にかなっています。シングルトンはインスタンスが 1 回だけ作成されるため特別です。一方、メタクラスは、通常のクラスとは異なる動作をさせる、作成されたクラスのカスタム実装です。メタクラスを使用すると、シングルトン クラス定義をカスタマイズする必要がある場合に、より詳細な制御が可能になります。
もちろん
シングルトンには多重継承は必要ありません (メタクラスは基底クラスではないため)。ただし、継承でクラスのサブクラスを作成するには、シングルトンがclass は最初のメタクラスです。左端のメタクラスは __call__ を再定義します。これが問題になる可能性は低いです。インスタンス ディクショナリはインスタンスの名前空間にないため、誤って上書きされることはありません。
シングルトン パターンは、各クラスが 1 つのことだけを実行する必要があるという意味の「単一責任の原則」に違反しているということも聞きます。こうすることで、コードは独立していてカプセル化されているため、別のコードを変更する必要があるときにコードの動作が壊れることを心配する必要がなくなります。メタクラス実装はこのテストに合格します。メタクラスはパターンを強制し、シングルトンであることを意識する必要のないクラスとサブクラスを作成する責任があります。 メソッド 1 は、「MyClass 自体はクラスではなく関数であるため、クラス メソッドを呼び出すことができません」と指摘したように、このテストに失敗します。
Python 2 および 3 の互換バージョン
Python 2 および 3 でコードを記述するには、もう少し複雑なスキームが必要です。通常、メタクラスは型クラスのサブクラスであるため、メタクラスを使用して、実行時にメタクラスとして中間基本クラスを動的に作成し、その基本クラスをパブリック シングルトン基本クラスの基本クラスとして使用できます。これは次のように言うは易く行うは難しです:
def singleton(class_): instances = {} def getinstance(*args, **kwargs): if class_ not in instances: instances[class_] = class_(*args, **kwargs) return instances[class_] return getinstance @singleton class MyClass(BaseClass): pass
このアプローチの皮肉の 1 つは、サブクラス化を使用してメタクラスを実装していることです。考えられる利点の 1 つは、純粋なメタクラスとは異なり、isinstance(inst, Singleton) が True を返すことです。
訂正
別のトピックに関して、お気づきかもしれませんが、元の投稿の基本クラスの実装が間違っていました。クラス内の _instances を参照するには、呼び出し時には実際のクラスがまだ作成されていないため、super() またはクラス メソッドの静的メソッドを使用する必要があります。これはすべて、メタクラスの実装にも当てはまります。
class Singleton(object): _instance = None def __new__(class_, *args, **kwargs): if not isinstance(class_._instance, class_): class_._instance = object.__new__(class_, *args, **kwargs) return class_._instance class MyClass(Singleton, BaseClass): pass
以上がPython でシングルトンを実装する最良の方法は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

pythonisbothcompiledinterted.whenyourunapythonscript、itisfirstcompiledintobytecode、これはdenepythonvirtualmachine(pvm).thishybridapproaChallowsforplatform-platform-denodent-codebutcututicut。

Pythonは厳密に行ごとの実行ではありませんが、最適化され、インタープレーターメカニズムに基づいて条件付き実行です。インタープリターは、コードをPVMによって実行されるBytecodeに変換し、定数式または最適化ループを事前促進する場合があります。これらのメカニズムを理解することで、コードを最適化し、効率を向上させることができます。

Pythonに2つのリストを接続する多くの方法があります。1。オペレーターを使用しますが、これはシンプルですが、大きなリストでは非効率的です。 2。効率的ですが、元のリストを変更する拡張メソッドを使用します。 3。=演算子を使用します。これは効率的で読み取り可能です。 4。itertools.chain関数を使用します。これはメモリ効率が高いが、追加のインポートが必要です。 5。リストの解析を使用します。これはエレガントですが、複雑すぎる場合があります。選択方法は、コードのコンテキストと要件に基づいている必要があります。

Pythonリストをマージするには多くの方法があります。1。オペレーターを使用します。オペレーターは、シンプルですが、大きなリストではメモリ効率的ではありません。 2。効率的ですが、元のリストを変更する拡張メソッドを使用します。 3. Itertools.chainを使用します。これは、大規模なデータセットに適しています。 4.使用 *オペレーター、1つのコードで小規模から中型のリストをマージします。 5. numpy.concatenateを使用します。これは、パフォーマンス要件の高い大規模なデータセットとシナリオに適しています。 6.小さなリストに適したが、非効率的な追加方法を使用します。メソッドを選択するときは、リストのサイズとアプリケーションのシナリオを考慮する必要があります。

compiledlanguagesOfferspeedandsecurity、foredlanguagesprovideeaseofuseandportability.1)compiledlanguageslikec arefasterandsecurebuthavelOnderdevelopmentsplat dependency.2)

Pythonでは、forループは反復可能なオブジェクトを通過するために使用され、条件が満たされたときに操作を繰り返し実行するためにしばらくループが使用されます。 1)ループの例:リストを通過し、要素を印刷します。 2)ループの例:正しいと推測するまで、数値ゲームを推測します。マスタリングサイクルの原則と最適化手法は、コードの効率と信頼性を向上させることができます。

リストを文字列に連結するには、PythonのJoin()メソッドを使用して最良の選択です。 1)join()メソッドを使用して、 '' .join(my_list)などのリスト要素を文字列に連結します。 2)数字を含むリストの場合、連結する前にマップ(str、数字)を文字列に変換します。 3) '、'などの複雑なフォーマットに発電機式を使用できます。 4)混合データ型を処理するときは、MAP(STR、Mixed_List)を使用して、すべての要素を文字列に変換できるようにします。 5)大規模なリストには、 '' .join(lage_li)を使用します

pythonusesahybridapproach、コンコイリティレーショントビテコードと解釈を組み合わせて、コードコンピレッドフォームと非依存性bytecode.2)


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール
