I have an object Vm of Type
<class 'azure.mgmt.compute.v2019_07_01.models._models_py3.VirtualMachine'>
I want to iterate over this object by a loop so that I don’t have to manually extract the values.
Yes I’ve tried isinstance
to check whether the value is of type <class 'azure.mgmt.compute.v2019_07_01.models._models_py3.VirtualMachine'>
and extract but in the next iteration it fails.
For example let’s consider vm to be an object
- to access the vm size I will have to do
vm.hardware_profile.vm_size
- and similarly to access os type value I will have to do this
vm.storage_profile.os_disk.os_type
What I’m trying to achieve here is that if I pass the vm
object it should return all the end values. Any help or tips are greatly appreciated and thanks in advance
The code that I have written
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)))
And the output that i’ve been getting
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
Output that I expect:
it should extract all the objects which are there in the Input
Advertisement
Answer
You can use recursion. Here I’m using hasattr
to check if it’s has __dict__
attribute(vars()
method return the results of 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
Example:
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
Output:
>>> 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}]}