使用Python 2.7.10,我有这个脚本:
#!/usr/bin/python
#Do `sudo pip install boto3` first
import boto3
import json
def generate(key, value):
"""
Creates a nicely formatted Key(Value) item for output
"""
return '{}={}'.format(key, value)
def main():
ec2 = boto3.resource('ec2', region_name="us-west-2")
volumes = ec2.volumes.all()
for vol in volumes:
#print(vol.__str__())
#print(vol.__dict__)
print vol
# vol object has many attributes, which can be another class object.
# For ex:
#vol.volume_id),
#vol.availability_zone),
#vol.volume_type),
# only process when there are tags to process
# HERE: tags is another object which can contain a dict/list
#if vol.tags:
# for _ in vol.tags:
# # Get all of the tags
# output_parts.extend([
# generate(_.get('Key'), _.get('Value')),
# ])
# output everything at once.
print ','.join(output_parts)
if __name__ == '__main__':
main()
是否有一个函数可以使用一次调用递归地打印所有对象的属性?如何在一次调用中打印 val.xxxxx 和 val.tags.xxxx 的值。
我尝试使用
.__dict__
或 .__str__()
打印对象,但没有帮助。
这是一个函数,您可以将其放入对象的 str 中。 您也可以直接调用它,传入您想要打印的对象。 该函数返回一个字符串,表示对象内容的格式良好的遍历。
感谢来自forum.pythonistacafe.com 的@ruud 提出了这个解决方案。
def obj_to_string(obj, extra=' '):
return str(obj.__class__) + '\n' + '\n'.join(
(extra + (str(item) + ' = ' +
(obj_to_string(obj.__dict__[item], extra + ' ') if hasattr(obj.__dict__[item], '__dict__') else str(
obj.__dict__[item])))
for item in sorted(obj.__dict__)))
class A():
def __init__(self):
self.attr1 = 1
self.attr2 = 2
self.attr3 = 'three'
class B():
def __init__(self):
self.a = A()
self.attr10 = 10
self.attrx = 'x'
class C():
def __init__(self):
self.b = B()
class X():
def __init__(self):
self.abc = 'abc'
self.attr12 = 12
self.c = C()
def __str__(self):
return obj_to_string(self)
x = X()
print(x)
输出:
<class '__main__.X'>
abc = abc
attr12 = 12
c = <class '__main__.C'>
b = <class '__main__.B'>
a = <class '__main__.A'>
attr1 = 1
attr2 = 2
attr3 = three
attr10 = 10
attrx = x
这不是我的(我忘记了作者),但经过重新设计以更好地理解。您可以使用 attrs Define 和 asdict 递归创建参数字典
from typing import Any
def rec_print(map_obj: dict | Any):
# Tree variants
end_tree = "└─ "
pipe_tree = "│ "
tee_tree = "├─ "
blank_tree = " "
# Process object repr to pretty print
def _clear_obj_repr(obj):
return repr(obj).split("at")[0].replace("<", "").replace(">", "").strip()
# Recursive tree get
def _get_recursive_repr(map_obj: dict | Any, name: str = "", header: str = "", last=True):
# End point in recursion
if not isinstance(map_obj, dict):
if "<" in repr(map_obj):
obj_repr = _clear_obj_repr(map_obj)
else:
obj_repr = repr(map_obj)
return f"{header}{end_tree if last else tee_tree}{name}: {obj_repr}\n"
# Continue recursion
result = f"{header}{end_tree if last else tee_tree}{name}\n" # Header of local/global tee
last_key = list(map_obj.keys())[-1]
for key, value in map_obj.items():
inner_result = _get_recursive_repr(
value,
name=key,
header=f"{header}{blank_tree if last else pipe_tree}",
last=key == last_key,
)
result += inner_result[6:] # Add tree leaf, delete first 6 symbols to shift left all tree
return result
result = _get_recursive_repr(map_obj)
print(result[4:]) # Delete first empty header
rec_print(
dict(
f=dict(b=lambda x: x * 2),
a=1234,
n=dict(
p=3,
g=dict(a=2, h=5),
),
)
)
出:
f
└─ b: function lambda
a: 1234
n
├─ p: 3
└─ g
├─ a: 2
└─ h: 5
对于 attrs 类
from attrs import define, asdict
@define
class A:
g: str = "wq"
q: int = 2
@define
class T:
d: int = 3
g: A = A()
a = T()
rec_print(asdict(a))
出:
d: 3
g
├─ g: 'wq'
└─ q: 2