[解決済み] 名前付きタプルおよびオプションのキーワード引数のデフォルト値
質問
長い中空の "data" クラスを名前付きタプルに変換しようとしています。私のクラスは現在このような感じです。
class Node(object):
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
に変換した後
namedtuple
のように見える。
from collections import namedtuple
Node = namedtuple('Node', 'val left right')
しかし、ここで問題が発生します。私のオリジナルのクラスでは、値だけを渡すことができ、名前付き/キーワードの引数にデフォルト値を使用することで、デフォルトをケアしていました。みたいな感じ。
class BinaryTree(object):
def __init__(self, val):
self.root = Node(val)
しかし、リファクタリングされた名前付きタプルの場合、すべてのフィールドを渡す必要があるため、これはうまくいきません。もちろん
Node(val)
を
Node(val, None, None)
が、私の好みではありません。
このように、コードを複雑にすることなく、書き直しを成功させる良いトリックは存在するのでしょうか(メタプログラミング)、それとも薬を飲み込んで、"検索と置換"を進めるべきでしょうか?)
どのように解決するのですか?
Python 3.7
を使用します。 デフォルト パラメータを使用します。
>>> from collections import namedtuple
>>> fields = ('val', 'left', 'right')
>>> Node = namedtuple('Node', fields, defaults=(None,) * len(fields))
>>> Node()
Node(val=None, left=None, right=None)
あるいは、より良い方法は、新しい データクラス ライブラリは、namedtupleよりずっといい感じです。
>>> from dataclasses import dataclass
>>> from typing import Any
>>> @dataclass
... class Node:
... val: Any = None
... left: 'Node' = None
... right: 'Node' = None
>>> Node()
Node(val=None, left=None, right=None)
Python 3.7以前
設定
Node.__new__.__defaults__
をデフォルト値に設定します。
>>> from collections import namedtuple
>>> Node = namedtuple('Node', 'val left right')
>>> Node.__new__.__defaults__ = (None,) * len(Node._fields)
>>> Node()
Node(val=None, left=None, right=None)
Python 2.6以前
設定
Node.__new__.func_defaults
をデフォルト値に設定します。
>>> from collections import namedtuple
>>> Node = namedtuple('Node', 'val left right')
>>> Node.__new__.func_defaults = (None,) * len(Node._fields)
>>> Node()
Node(val=None, left=None, right=None)
ご注文
Pythonのすべてのバージョンにおいて、namedtupleに存在するよりも少ない数のデフォルト値を設定した場合、そのデフォルト値は右端のパラメータに適用されます。これにより、いくつかの引数を必須引数として保持することができます。
>>> Node.__new__.__defaults__ = (1,2)
>>> Node()
Traceback (most recent call last):
...
TypeError: __new__() missing 1 required positional argument: 'val'
>>> Node(3)
Node(val=3, left=1, right=2)
Python 2.6~3.6用ラッパー
これはあなたのためのラッパーで、(オプションで)デフォルト値を
None
. これは必須引数をサポートしていません。
import collections
def namedtuple_with_defaults(typename, field_names, default_values=()):
T = collections.namedtuple(typename, field_names)
T.__new__.__defaults__ = (None,) * len(T._fields)
if isinstance(default_values, collections.Mapping):
prototype = T(**default_values)
else:
prototype = T(*default_values)
T.__new__.__defaults__ = tuple(prototype)
return T
例
>>> Node = namedtuple_with_defaults('Node', 'val left right')
>>> Node()
Node(val=None, left=None, right=None)
>>> Node = namedtuple_with_defaults('Node', 'val left right', [1, 2, 3])
>>> Node()
Node(val=1, left=2, right=3)
>>> Node = namedtuple_with_defaults('Node', 'val left right', {'right':7})
>>> Node()
Node(val=None, left=None, right=7)
>>> Node(4)
Node(val=4, left=None, right=7)
関連
-
Pythonの画像ファイル処理用ライブラリ「Pillow」(グラフィックの詳細)
-
[解決済み】pygame.error: ビデオシステムが初期化されていない
-
[解決済み】TypeError: 系列を <class 'float'> に変換することができません。
-
[解決済み] 最小限の驚き」と「変更可能なデフォルトの引数
-
[解決済み] パラメータに**(ダブルスター/アスタリスク)、*(スター/アスタリスク)がありますが、これはどういう意味ですか?
-
[解決済み] NaN値をチェックするにはどうすればよいですか?
-
[解決済み] intの最大値、最小値
-
[解決済み] Argparse オプションの位置引数?
-
[解決済み] オプションの引数を持つPython関数を作成するにはどうしたらいいですか?
-
[解決済み】C# 4.0のオプションのout/ref引数
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Python 人工知能 人間学習 描画 機械学習モデル作成
-
Python機械学習Githubが8.9Kstarsに達したモデルインタープリタLIME
-
Pythonによるjieba分割ライブラリ
-
Pythonショートビデオクローラーチュートリアル
-
[解決済み】ImportError: sklearn.cross_validation という名前のモジュールがない。
-
[解決済み】Python regex AttributeError: 'NoneType' オブジェクトに 'group' 属性がない。
-
[解決済み】 NameError: グローバル名 'xrange' は Python 3 で定義されていません。
-
[解決済み】csv.Error:イテレータはバイトではなく文字列を返すべき
-
[解決済み】LogisticRegression: Pythonでsklearnを使用して、未知のラベルタイプ: '連続'を使用しています。
-
[解決済み】データクラスとは何ですか、一般的なクラスとどう違うのですか?