forked from pythonnet/pythonnet
-
Notifications
You must be signed in to change notification settings - Fork 0
Customizing interop
lidanger edited this page May 9, 2019
·
2 revisions
默认情况下,当从 Python 中调用 C# 代码时,Python.NET 将只执行以下转换: 将原始 Python 类型转换为 C# 对应类型,将 Python 列表转换为 C# 数组,将以前传递给 C# 的 .NET 对象解包为它们自己。其他所有内容都作为 PyObject
的实例传递。
如果这还不够 (例如,当你有用于 Python 类的 C# 包装器时),你可能希望对从 Python 传递过来的参数执行自定义转换。在这种情况下,您可以实现 IPyArgumentConverter
接口,或者从 DefaultPyArgumentConverter
派生,并重载它的 TryConvertArgument
方法。然后你可以告诉 Python.NET,当试图使用 PyArgConverterAttribute
调用类/程序集中的任何方法时,使用你的转换器。
例如,无论何时需要 int
参数,下面的转换器都会尝试将参数值 (由 Python 传递) 转换为 string
,然后将该字符串解析为 int
。
class CustomArgConverter : DefaultPyArgumentConverter {
public override bool TryConvertArgument(IntPtr pyarg, Type parameterType, bool needsResolution,
out object arg, out bool isOut) {
if (parameterType != typeof(int))
// 默认行为
return base.TryConvertArgument(pyarg, parameterType, needsResolution, out arg, out isOut);
bool isString = base.TryConvertArgument(pyarg, typeof(string), needsResolution,
out arg, out isOut);
if (!isString) return false;
int number;
if (!int.TryParse((string)arg, out number)) return false;
arg = number;
return true;
}
}
它可以附加到这样的类(在 C# 中):
[PyArgConverter(typeof(CustomArgConverter))]
class CustomArgMarshaling {
public object LastArgument { get; private set; }
public void CallWithInt(int value) => this.LastArgument = value;
}
在 Python 中:
clrObject = CustomArgMarshaling()
clrObject.CallWithInt("42")
注意,这个特性注释也将用于构造函数和属性访问器。