2

だから私は同様の質問を見て、これに対するいくつかの解決策を見つけましたが、これを行う方法がよくわかりません.

私がやろうとしているのは、文字列からクラスにメソッドを追加することです。メソッドでこれを行うことができますが、追加のメソッドで属性としてsetattr()使用することはできません。self以下に例を示します: (変数名については申し訳ありませんが、アイデアをモックアップするときは常に yolo を使用します)

class what:
    def __init__(self):
        s = 'def yolo(self):\n\tself.extra = "Hello"\n\tprint self.extra'
        exec(s)
        setattr(self,"yolo",yolo)

what().yolo()

これを返します:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: yolo() takes exactly 1 argument (0 given)

そして、次のs = 'def yolo():\n\tself.extra = "Hello"\n\tprint self.extra' 結果が得られた場合:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 2, in yolo
NameError: global name 'self' is not defined

これは基本的に、クラスのメソッドを動的に作成できないことを意味します。これは、クラスの残りの部分がアクセスできる変数にメソッドがアクセスできないため、悪い習慣であり、pythonic ではないことがわかっています。

助けていただければ幸いです。

4

2 に答える 2

6

関数をメソッドに変換するには、関数をクラス インスタンスにバインドする必要があります。でラップすることで実行できますtypes.MethodType

import types

class what:
    def __init__(self):
        s = 'def yolo(self):\n\tself.extra = "Hello"\n\tprint self.extra'
        exec(s)
        self.yolo = types.MethodType(yolo, self)

what().yolo()

exec余談ですが、この場合、なぜ必要なのですか?あなたも同様に書くことができます

import types

class what:
    def __init__(self):
        def yolo(self):
            self.extra = "Hello"
            print self.extra

        self.yolo = types.MethodType(yolo, self)

what().yolo()

編集:完全を期すために、記述子プロトコルによる解決策を好むかもしれません:

class what:
    def __init__(self):
        def yolo(self):
            self.extra = "Hello"
            print self.extra

        self.yolo = yolo.__get__(self)

what().yolo()
于 2013-10-06T05:11:17.807 に答える
1

別の方法は、私にはよりエレガントに思えます:

class what:
    pass

ld = {}
exec("""
def yolo(self):
    self.extra = "Hello"
    print(self.extra)
""", None, ld)
# print('locals got: {}'.format(ld))
for name, value in ld.items():
    setattr(what, name, value)

what().yolo()
于 2016-07-20T20:43:03.750 に答える