Получение и хранение методов класса Python - PullRequest
1 голос
/ 12 мая 2011

Прежде всего, я новичок в Python и немного заржавел в .NET, так что терпите меня, если это звучит слишком очевидно. Предполагая следующие классы Python;

class foo1(object):
      def bar1(self):
         print "bar1 called."
      def bar2(self):
         print "bar2 called."
class foo2 ..... same as above

Я хочу где-то хранить методы класса и вызывать их для объекта по собственному выбору . Это то, что я придумал.

ObjectOperations ops = engine.Operations;
IList<string> members = ops.GetMemberNames(scope);
foreach(string member in members)
{
   if(member.StartsWith("foo"))
      {
         dynamic klass= scope.GetVariable(member);
         dynamic instance= klass();
         //for brevity I am skipping the enumeration of
         //function names here.
         dynamic func = ops.GetMember(instance, "bar1");//and store it somewhere
         Action act = ops.ConvertTo<Action>(func); //This part is not really necessary

       }
}

Что я хочу сделать, так это вызвать функцию (типа IronPython.Runtime.Method) для экземпляра, который я создаю позже. Из того, что я понял из источника IronPython, что экземпляр создается в камне при его создании, и я не могу его изменить. Есть ли способ сделать это? Я также не уверен, в каком контексте (области видимости), чтобы запустить функцию, или я не должен беспокоиться обо всем этом.

В ObjectOperations есть метод MemberInvoke, который принимает объект и имя члена, но я бы предпочел тип вызова MethodInfo.Invoke как по стилю, так и по соображениям производительности.

Любые указатели будут с благодарностью.

P.S. Я использую IronPython 2.7 и .Net4.0, кстати ..

1 Ответ

3 голосов
/ 12 мая 2011

Да, это на самом деле очень просто. В Python методы могут быть вызваны как связанные методы, такие как:

x = C().f  # produces a bound method
x() # invokes the bound method

Что совпадает с:

C().f()

Или они могут быть вызваны с явным параметром self:

C.f(C())

Это работает так же, как и API-интерфейсы хостинга, поэтому все, что вам нужно сделать, это что-то вроде:

dynamic klass = scope.GetVariable(member);
dynamic func = ops.GetMember(klass, "bar1");

// and then later:
func(inst);
...