boto实例.__dict__['tags']['Name']输出问题

0 投票
1 回答
4573 浏览
提问于 2025-04-17 12:03

更新:


我按照下面的建议做了,但是输出中仍然出现了 KeyError:'Name' 的错误,尽管输出结果是正确的。

这是输出结果:

us-west-1 EC2Connection:
ec2.us-west-1.amazonaws.com 
Showing all of your current instances 
Proxy-44-1000-Enrollments 
Proxy-45-1000-Enrollments 
Proxy-48-1000-Enrollments 
Proxy-49-1000-Enrollments 
Proxy-59-1000-Enrollments 
Proxy-67-1000-Enrollments 

Traceback (most recent call last): File "/Users/xxxxx/xxxx/boto/instanceid.py", 
line 43, in <module> print "\t%s" % (instance.tags['Name']) if instance.state ==
'running' else instance.state KeyError: 'Name'

最初的问题:

我想从 AWS 中获取实例 ID 列表以及它们的 "Name" 标签,使用的是 boto 这个库。我在网上找到了一种可以附加到实例对象上的方法,叫做 __dict__,这个方法似乎很好用。不过,我只想在使用这个方法时提取出 "name" 标签,但我总是遇到 "Key Error:'Name'" 的错误。

基本上,这段代码是可以工作的:

# Creating connection object to EC2
conn = boto.connect_ec2()

regions = boto.ec2.regions()

# the 5 element in the array is "us-west-1" and setting the object to connect
us = regions[5]
print us.name
conn_us = us.connect()
print conn_us

filters = {'key-name' : 'misc-key'}

all_inst = conn_us.get_all_instances(filters=filters)

print "Showing all of your current instances" 
for res in all_inst: 
    # each reservation have a instance: 
    for instance in res.instances: 
        print "\t%s: \t%s" % (instance.id, instance.__dict__['tags'])

不过输出结果有点奇怪:

us-west-1
EC2Connection:ec2.us-west-1.amazonaws.com
Showing all of your current instances
    i-xxxxxxxx:     {u'Name': u'Proxy-xx-1000-Enrollments'}
    i-xxxxxxxx:     {u'Name': u'Proxy-xx-1000-Enrollments'}
    i-xxxxxxxx:     {u'Name': u'Proxy-xx-1000-Enrollments'}
    i-xxxxxxxx:     {u'Name': u'Proxy-xx-1000-Enrollments'}
    i-xxxxxxxx:     {u'Name': u'Proxy-xx-1000-Enrollments'}

当我对 __dict__ 方法进行修改,只提取 "name" 时,它可以工作(或者看起来可以工作),但还是会抛出一个错误:

这是代码的修改:

print "\t%s: \t%s" % (instance.id, instance.__dict__['tags']['Name'])

这是输出结果:

us-west-1
EC2Connection:ec2.us-west-1.amazonaws.com
Showing all of your current instances
    i-xxxxxxxx:     Proxy-xx-1000-Enrollments
    i-xxxxxxxx:     Proxy-xx-1000-Enrollments
    i-xxxxxxxx:     Proxy-xx-1000-Enrollments
    i-xxxxxxxx:     Proxy-xx-1000-Enrollments
    i-xxxxxxxx:     Proxy-xx-1000-Enrollments
    i-xxxxxxxx:     Proxy-xx-1000-Enrollments

Traceback (most recent call last):
  File "/Users/xxxxxx/xxx.xxx/boto/instanceid.py", line 43, in <module>
    print "\t%s: \t%s" % (instance.id, instance.__dict__['tags']["Name"])
KeyError: 'Name'

我更喜欢这个输出,没有 错误 - 有谁能告诉我我哪里做错了吗?

谢谢

1 个回答

4

为什么不直接访问标签属性呢?通过 __dict__ 来获取它并不是很符合 Python 的风格:

instance.tags['Name']

你可能还想看看实例的状态,因为从 get_all_instances() 获取的 Reservation 对象中,有些实例可能是最近被终止的。你可以只报告正在运行的实例的名称,而对于其他实例则报告它们的状态(注意,这里的 .state 检查只是一个例子,用来展示 A if cond else B 这种写法。你还需要自己动手试试):

instance.tags['Name'] if instance.state == 'running' else instance.state

如果你只是想避免 KeyError 错误并返回一个默认值,可以使用 dict.get()

instance.tags.get('Name')  
# or with a default
instance.tags.get('Name', '--')

这里有一段摘自 boto ec2 教程 的内容,提到了 Reservation 对象和实例状态。

如果你只想获取所有正在运行的实例的列表,可以使用连接对象的 get_all_instances 方法。请注意,返回的列表实际上是 Reservation 对象的列表(其中包含实例),而且这个列表可能在实例被终止后的短时间内还会包含最近被终止的实例。

撰写回答