83844


pythonの属性に、属性名を格納した文字列の変数を使って参照する方法を教えていただけないでしょうか。

例えばmodelというオブジェクトに、属性名backbone.body.conv1を格納した文字列

[code]

    x="backbone"
    y="body"
    z="conv1"
    
[/code]

で、`model.x.y.z`のように参照して、データを`nn.Conv2d(3, 64, kernel_size=(7,
7))`から`nn.Conv2d(3, 64, kernel_size=(3, 3))`に書き換えたいと考えております。  
現在は下記のコードのようにexec関数を使っておりますが、この関数を使う以外の方法でアクセスする方法はありますでしょうか。

[code]

    import torchvision
    import torch.nn as nn
    
    
    model = torchvision.models.detection.__dict__["maskrcnn_resnet50_fpn"](num_classes=81, pretrained=False)
    
    # 書き換え前の状態を確認
    print("model.backbone.body.conv1:", model.backbone.body.conv1)
    # model.backbone.body.conv1: Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
    
    # exec()関数で書き換え
    x="backbone"
    y="body"
    z="conv1"
    module="model.{}.{}.{} = nn.Conv2d(3, 64, kernel_size=(3, 3))".format(x,y,z)
    exec(module)
    
    # 書き換え後の状態を確認
    print("model.backbone.body.conv1:", model.backbone.body.conv1)
    # model.backbone.body.conv1: Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1))
    
[/code]

もし対処方法をご存知でしたら教えていただければ幸いです。何卒宜しくお願い致します。


CC BY-SA 4.0
2021-03-30T01:04:30.907
74977
2021-11-28T10:40:45.013
2021-03-30T01:13:33.413
30280
30280
question
python
pythonの属性に、属性名を格納した文字列の変数を使って参照する方法


execの代わりにevalを使うのはいかがでしょう

[code]

    s = """"model.{}.{}.{} = nn.Conv2d(3, 64, kernel_size=(3, 3))".format(x,y,z)"""
    eval(s)
    print("model.backbone.body.conv1:", model.backbone.body.conv1)
    
[/code]

execの場合と同じ結果になりました。

[code]

    model.backbone.body.conv1: Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1))
    
[/code]

* * *

どうしてexec以外の実現方法を探しているのかを質問に明示した方がよいと思います。  
その内容によりますが、execの問題はevalでもだめなような気がします。


CC BY-SA 4.0
2021-03-31T00:09:05.780
74994
2021-03-31T00:44:13.210
2021-03-31T00:44:13.210
35558
35558
74977
answer


質問のコメント欄で紹介いただいたサイト（[[Python]
インスタンスのプロパティへ動的にアクセスする](https://www.yoheim.net/blog.php?q=20161002)
）を参考に解決できましたので、自己回答させていただきます。

pythonの組み込み関数のgetattr()を使うと、インスタンスのプロパティにアクセスできます。  
下記のように多重に使うことで無事に実行できました。

[code]

    print(getattr(getattr(getattr(model, x), y), z))
    
[/code]


CC BY-SA 4.0
2021-11-28T10:40:45.013
83844
2021-11-28T10:40:45.013
30280
74977
answer