【问题标题】:I want to extract all the values that a class object holds我想提取一个类对象拥有的所有值
【发布时间】:2021-04-02 17:20:55
【问题描述】:

我有一个类型为 Vm 的对象 <class 'azure.mgmt.compute.v2019_07_01.models._models_py3.VirtualMachine'> 我想通过循环遍历这个对象,这样我就不必手动提取值了。

是的,我尝试isinstance 来检查值是否为<class 'azure.mgmt.compute.v2019_07_01.models._models_py3.VirtualMachine'> 类型并提取,但在下一次迭代中它失败了。

例如,让我们将 vm 视为一个对象

  • 要访问虚拟机大小,我必须这样做vm.hardware_profile.vm_size
  • 与访问操作系统类型值类似,我将不得不这样做vm.storage_profile.os_disk.os_type

我在这里想要实现的是,如果我传递 vm 对象,它应该返回所有的最终值。非常感谢任何帮助或提示,并在此先感谢

我写的代码

def iterdict(d):
    for k,v in d.items():        
        if isinstance(v, dict):
            iterdict(v)
        else:            
            print (k,":",v)

for vm in compute_client.virtual_machines.list_all():
    print(iterdict(vars(vm)))

以及我得到的输出

name : arun-scheduler
type : Microsoft.Compute/virtualMachines
location : eastus
ml-scheduler : Test
stop_time : 2020-12-25 15:22:40.042295
plan : None
resources : None
identity : None
zones : None
hardware_profile : {'additional_properties': {}, 'vm_size': 'Standard_A1_v2'}
storage_profile : {'additional_properties': {}, 'image_reference': <azure.mgmt.compute.v2019_07_01.models._models_py3.ImageReference object at 0x000001AD6D5964C0>, 'os_disk': <azure.mgmt.compute.v2019_07_01.models._models_py3.OSDisk object at 0x000001AD6D596EB0>, 'data_disks': []}
additional_capabilities : None
os_profile : {'additional_properties': {}, 'computer_name': 'arun-scheduler', 'admin_username': 'xxxxxx', 'admin_password': None, 'custom_data': None, 'windows_configuration': None, 'linux_configuration': <azure.mgmt.compute.v2019_07_01.models._models_py3.LinuxConfiguration object at 0x000001AD6D596100>, 'secrets': [], 'allow_extension_operations': True, 'require_guest_provision_signal': True}
network_profile : {'additional_properties': {}, 'network_interfaces': [<azure.mgmt.compute.v2019_07_01.models._models_py3.NetworkInterfaceReference object at 0x000001AD6D596850>]}
diagnostics_profile : {'additional_properties': {}, 'boot_diagnostics': <azure.mgmt.compute.v2019_07_01.models._models_py3.BootDiagnostics object at 0x000001AD6D5966A0>}
availability_set : None
virtual_machine_scale_set : None
proximity_placement_group : None
priority : None

我期望的输出:

它应该提取输入中的所有对象

【问题讨论】:

  • 您可以使用另一个循环并检查字典的值,在循环内您可以使用您正在使用的相同代码
  • 它不是一个级别....我需要一个递归答案...以便它可以从对象中提取所有值
  • 这可能是不可能的。因为核心代码可能用另一种语言实现,而这只是一个包装器,所以您可能无法通过 dict 方法访问元素。相反,您将不得不使用 dir 函数,删除所有魔术方法并尝试查找所有元素。
  • 谢谢,但我刚刚尝试了 dir .....它似乎不是我正在寻找的解决方案......但无论如何都感谢

标签: python azure loops recursion


【解决方案1】:

Microsoft Azure 的 Python API 的优点是它内置了很多功能,并且代码是开源的。例如,查看 code 的确切课程。这继承自 msrest.serialization.Model,您也可以找到 code 的。

请注意,所有 Model 类都提供了一个 .serialize() 方法,该方法将类转换为 json 字符串以传递给 Azure 远程服务。在做任何不必要的复杂和本土化的事情之前,我会尝试在您的 VirtualMachine 对象上调用它,看看它是否为您提供了可以使用的字符串表示。

【讨论】:

    【解决方案2】:

    您可以使用递归。这里我使用hasattr来检查它是否有__dict__属性(vars()方法返回obj.__dict__的结果)。

    def props(x):
        if hasattr(x, '__dict__'):
            res = {}
            for k, v in vars(x).items():
                if isinstance(v, list):
                    res[k] = [props(e) for e in v if hasattr(e, '__dict__')]
                elif hasattr(v, '__dict__'):
                    res[k] = props(v)
                else:
                    res[k] = v
            return res
    

    示例:

    class A:
        def __init__(self, p, q):
            self.p = p
            self.q = q
    
    class B:
        def __init__(self, x, y):
            self.x = x
            self.y = y
    
    class C:
        def __init__(self, a, b, lst):
            self.a = a
            self.b = b
            self.lst = lst
    

    输出:

    >>> a = A(123, 'abc')
    >>> b = B(a, {'xyz': 123})
    >>> c = C(a, b, [B(a, 1), B(a, 2)])
    >>> props(c)
    {'a': {'p': 123, 'q': 'abc'},
     'b': {'x': {'p': 123, 'q': 'abc'}, 'y': {'xyz': 123}},
     'lst': [{'x': {'p': 123, 'q': 'abc'}, 'y': 1},
      {'x': {'p': 123, 'q': 'abc'}, 'y': 2}]}
    

    【讨论】:

    • 这里有一个缺陷..如果您可以在我发布的输出中看到 network_profile : {'additional_properties': {}, 'network_interfaces': []} 它具有对象列表,并且无法从中提取数据
    • 这将是一个很大的帮助
    • 谢谢你..它的工作方式正是我想要的
    【解决方案3】:

    你可以使用clasObject.__dict__,它会返回一个对象封装变量的字典

    【讨论】:

    • 它没有完全提取...它的行为与 vars(object) 相同
    • 我猜现在你的问题是解封装嵌套对象。据我所知,您需要为它创建一个递归函数。在调用vars(object) 后循环遍历键,然后调用isinstance(key, type),如果它是真的那么它是一个可以解封装的对象。
    • 是的,我正在尝试做同样的事情......但我无法实现它......因为我也是编程新手
    猜你喜欢
    • 2014-09-01
    • 2012-07-18
    • 2022-11-13
    • 1970-01-01
    • 1970-01-01
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多