88613


Pythonで引数をインスタンス変数に代入する場合、以下の様な記述になると思いますが、このインスタンス変数の代入が冗長な感じがします。

この `self.x=x` を何行も書かないといけないのを省略する方法はありませんでしょうか？

[code]

    class hoge:
        def __init__(self,a,b,c,d,・・・)
            self.a=a
            self.b=b
            self.c=c
            ・
            ・
            ・
    
[/code]


CC BY-SA 4.0
2022-05-02T05:01:21.887
88609
2022-05-03T01:40:53.673
2022-05-02T05:22:48.040
3060
52439
question
python
pythonでインスタンス変数を自動で代入(?)する方法はありますか？


可読性は低いし、容易にエラーが発生するのでお勧めはしませんが、「できなくはない」という一例として。

[code]

    class hoge:
        def __init__(self, *args):
            [setattr(self, k, v) for k, v in zip('abc', args)]
    
    if __name__ == '__main__':
        v = hoge(1, 2, 3)
        print(v.a)
        print(v.b)
        print(v.c)
    
    #
    1
    2
    3
    
[/code]


CC BY-SA 4.0
2022-05-02T05:26:12.253
88611
2022-05-02T05:26:12.253
47127
88609
answer


引数が必要なら、代入文を冗長に感じることはないのでは  
代入文を冗長に感じるなら、冗長なのは引数の方なのでは  
というのが率直な感想です。

* * *

保持するデータを渡す引数が必要だが代入文は冗長、と感じるのならNamedTupleやデータクラスの出番だと思います。  
<https://docs.python.org/ja/3/library/typing.html#typing.NamedTuple>  
<https://docs.python.org/ja/3/library/dataclasses.html>


CC BY-SA 4.0
2022-05-02T06:05:16.193
88612
2022-05-02T06:05:16.193
12274
88609
answer


`self.name = name` のような記述を毎行記すのが大変という意味なら, [dataclasses ---
データクラス](https://docs.python.org/ja/3/library/dataclasses.html) があります

(記述例)

[code]

    from dataclasses import dataclass
    
    @dataclass
    class InventoryItem:
        """Class for keeping track of an item in inventory."""
        name: str
        unit_price: float
        quantity_on_hand: int = 0
    
        def total_cost(self) -> float:
            return self.unit_price * self.quantity_on_hand
    
[/code]

また `dataclasses.make_dataclass`もあり一行で記すことも可能らしいけど見やすいとは思えず  
たぶん, 別の目的のものだと思えます。

質問の意図が, 行が長すぎるという意味なら, クラスの設計に問題があるように思えます


CC BY-SA 4.0
2022-05-02T06:13:03.727
88613
2022-05-02T06:13:03.727
43025
88609
answer


`__init__()`の引数名を属性と見なす方法です。  
inspectモジュールを使って、`__init__()`の引数を取得し、引数の名前で属性を生成し、その属性に引数の値を設定する方法です。

[code]

    class hoge:
        def __init__(self, a, b, c, d):
            import inspect
            frame = inspect.currentframe()
            info = inspect.getargvalues(frame)
            args = dict({key: info.locals[key] for key in info.args[1:]})
            for k in args:
                setattr(self, k, args[k])
    
[/code]

他の回答者のコメントのとおり、明示的に属性に値を設定した方がよいと思いますが、何らかの事情があるのだと思い回答します。


CC BY-SA 4.0
2022-05-03T01:40:53.673
88629
2022-05-03T01:40:53.673
35558
88609
answer