ホームページ >バックエンド開発 >Python チュートリアル >Python データ構造: 過小評価されている Namedtuple (2)
Python ビデオ チュートリアルこのコラムでは引き続き、Python データ構造の Namedtuple について理解していきます。
パート 1Python データ構造: 過小評価されている Namedtuple (1)namedtuple の基本的な使用法について説明した後、この記事は続きます。
Python 3.7より前では、次のメソッドのいずれかを使用して単純なデータコンテナを作成できました:
attrs
通常のクラスを使用したい場合は、いくつかのメソッドを実装する必要があることを意味します。たとえば、通常のクラスでは、クラスのインスタンス化中にプロパティを設定するために __init__
メソッドが必要になります。クラスをハッシュ可能にしたい場合は、__hash__
メソッドを自分で実装することを意味します。異なるオブジェクトを比較するには、__eq__
メソッドを実装する必要もあります。最後に、デバッグを簡素化するには、__repr__
メソッドが必要です。
通常のクラスを使用して、色のユースケースを実装しましょう。
class Color: """A regular class that represents a color.""" def __init__(self, r, g, b, alpha=0.0): self.r = r self.g = g self.b = b self.alpha = alpha def __hash__(self): return hash((self.r, self.g, self.b, self.alpha)) def __repr__(self): return "{0}({1}, {2}, {3}, {4})".format( self.__class__.__name__, self.r, self.g, self.b, self.alpha ) def __eq__(self, other): if not isinstance(other, Color): return False return ( self.r == other.r and self.g == other.g and self.b == other.b and self.alpha == other.alpha )复制代码
上記のように、多くのメソッドを実装する必要があります。必要なのは、気を散らす詳細を気にせずにデータを保持するためのコンテナーだけです。繰り返しになりますが、人々が実装クラスを好む理由の主な違いは、通常のクラスが変更可能であることです。
実際、Data Classes
を導入する PEP では、それらを「デフォルト値を持つ可変の名前付きタプル」と呼んでいます (翻訳者注: Python 3.7 で導入されたデータ クラス、参考: docs.python.org /zh-cn/3/lib…
さあ、dataclasses
.
from dataclasses import dataclass ...@dataclassclass Color: """A regular class that represents a color.""" r: float g: float b: float alpha: float复制代码
を使ってそれを行う方法を見てみましょう! それは簡単です。 __init__
では、docstring の後にプロパティを定義するだけです。さらに、プロパティには型ヒントの注釈を付ける必要があります。
データ クラスは、変更可能であることに加えて、すぐに使用できるオプションのフィールドが提供されていますColor クラスにアルファ フィールドが必要ないとします。その後、それをオプションにできます。
from dataclasses import dataclassfrom typing import Optional ...@dataclassclass Color: """A regular class that represents a color.""" r: float g: float b: float alpha: Optional[float]复制代码
次のようにインスタンス化できます:
>>> blue = Color(r=0, g=0, b=255)复制代码
これらは可変なので、任意に変更できます。
>>> blue = Color(r=0, g=0, b=255) >>> blue.r = 1 >>> # 可以设置更多的属性字段 >>> blue.e = 10复制代码
それに比べて、namedtuple
にはデフォルトでオプションのフィールドがありません。それらを追加するには、少しのトリックとメタプログラミングが必要です。
__hash__ メソッドを追加するには、
unsafe_hash を
True に設定して不変にする必要があります:
@dataclass(unsafe_hash=True)class Color: ...复制代码もう 1 つの違いは次のとおりです。その解凍は名前付きタプル (第一級市民) の組み込み関数です。
data クラス に同じ動作を持たせたい場合は、自分で実装する必要があります。パフォーマンスの比較
from dataclasses import dataclass, astuple ...@dataclassclass Color: """A regular class that represents a color.""" r: float g: float b: float alpha: float def __iter__(self): yield from dataclasses.astuple(self)复制代码上記のように、データ クラスはフィールドへのアクセスがわずかに高速ですが、名前タプルよりも多くのメモリ領域を消費します。
名前付きタプルに型ヒントを追加する方法データ クラスは型を使用しますヒントはデフォルトで設定されています。名前付きタプルに配置することもできます。名前付きタプル注釈タイプをインポートし、それを継承することで、カラータプルに注釈を付けることができます。
In [6]: import sys In [7]: ColorTuple = namedtuple("Color", "r g b alpha") In [8]: @dataclass ...: class ColorClass: ...: """A regular class that represents a color.""" ...: r: float ...: g: float ...: b: float ...: alpha: float ...: In [9]: color_tup = ColorTuple(r=50, g=205, b=50, alpha=1.0) In [10]: color_cls = ColorClass(r=50, g=205, b=50, alpha=1.0) In [11]: %timeit color_tup.r36.8 ns ± 0.109 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) In [12]: %timeit color_cls.r38.4 ns ± 0.112 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) In [15]: sys.getsizeof(color_tup) Out[15]: 72In [16]: sys.getsizeof(color_cls) + sys.getsizeof(vars(color_cls)) Out[16]: 152复制代码
from typing import NamedTuple ...class Color(NamedTuple): """A namedtuple that represents a color.""" r: float g: float b: float alpha: float复制代码オプションのデフォルト値をnamedtupleに追加する方法前のセクションでは、データクラスがオプションの値を持つことができることを学びました。さらに、同じ動作を模倣するには、
Help on class Color in module __main__:class Color(builtins.tuple) | Color(r: float, g: float, b: float, alpha: Union[float, NoneType]) | | A namedtuple that represents a color. | | Method resolution order: | Color | builtins.tuple | builtins.object | | Methods defined here: | | __getnewargs__(self) | Return self as a plain tuple. Used by copy and pickle. | | __repr__(self) | Return a nicely formatted representation string | | _asdict(self) | Return a new dict which maps field names to their values.复制代码
結論
タプルは非常に強力なデータ構造です。これらにより、コードがよりクリーンになり、信頼性が高まります。新しい namedtuples の使用方法をいくつか学びましたので、ぜひご活用ください。
以上がPython データ構造: 過小評価されている Namedtuple (2)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。