在 Python.NET 中访问 C# 字典:TypeError:无法将字典更新序列元素 #0 转换为序列

问题描述

我一直在尝试使用 Python.NET 从一些 Python 代码访问 C# 字典。

尝试从 C# 字典显式创建 Python dict 失败并出现 TypeError: cannot convert dictionary update sequence element #0 to a sequence 错误

import clr

clr.AddReference('System')
clr.AddReference('System.Collections')

from System.Collections.Generic import Dictionary
from System import String
from System import Object

d = Dictionary[String,Object]()
d['Entry 1'] = 'test'
d['Entry 2'] = 12.3
print(f" d.Count : {d.Count}") # returns 2

py_dict = dict(d)
 d.Count : 2
Traceback (most recent call last):
  File "test_dict.py",line 21,in <module>
    py_dict = dict(d)
TypeError: cannot convert dictionary update sequence element #0 to a sequence

在我的实际代码中,c_sharp_obj 字典被声明为:

Dictionary<DescriptorType,IDescriptor> Descriptors { get; }

IDescriptor一个自定义的 C# 类:

public interface IDescriptor : Idisposable

DescriptorType一个 enum

public enum DescriptorType
{
  CharacteristicAggregateFormat   = 0x2905,CharacteristicExtendedProperties = 0x2900,CharacteristicPresentationFormat = 0x2904,CharacteristicUserDescription = 0x2901,ClientCharacteristicConfiguration = 0x2902,}

在 IronPython 上,我可以使用

迭代键和值
for k,v in  in dict(c_sharp_obj).iteritems():

如果我尝试:

print(c_sharp_obj)
print(type(c_sharp_obj))

我明白了:

System.Collections.Generic.Dictionary`2[DescriptorType,IDescriptor]
<class 'System.Collections.Generic.313,Culture=neutral,PublicKeyToken=null]]'>

我可以通过以下方式遍历字典:

for k in c_sharp_obj:
    print(k)
    print(type(k))

我得到:

[CharacteristicUserDescription,Type:CharacteristicUserDescription]
<class 'System.Collections.Generic.313,PublicKeyToken=null]]'>

我不应该将 DescriptorType 作为类型吗?如果我尝试使用键索引字典:

print(c_sharp_obj[k])

我得到一个 TypeError: No method matches given arguments: (<class 'System.Collections.Generic.313,PublicKeyToken=null]]'>)

我能够通过以下方式访问枚举值

enum_name = str(k).split(',')[0].replace('[','')
enum_value = System.Enum.Parse(clr.GetClrType(Arendi.BleLibrary.Service.DescriptorType),enum_name);
print(hex(enum_name))
print(c_sharp_obj[enum_name])

但行 print(c_sharp_obj[enum_name]) 给了我 Type:CharacteristicUserDescription 而不是 IDescriptor 对象。

如何遍历访问原始 C# 类的 C# 字典?

我使用的是 Python.NET 2.5.2。谢谢!!!

解决方法

您在使用 Python.NET 遍历 .NET 字典时看到的泛型类型 System.Collections.Generic.313 可能是 KeyValuePair<TKey,TValue> 的实例化。所以在你的循环中你可以访问 k.Keyk.Value。顺便说一句,您可以通过运行 dir(k) 发现。