如何使用包含字符串的局部变量来引用全局变量的名称

How to use local varaiable containing a string to reference the name of a Global Variable

我有一个脚本,我在其中尝试遍历字符串列表,然后获取当前变量的值,将其转换为大写,然后将结果用作变量名。最终结果将是设置 prometheus 指标的值,这是一个全局变量。

from prometheus_client import start_http_server, Gauge


# List of strings (global variables will be equal but upper-case)
MEASUREMENTS = ['x', 'y', 'z']

# Prometheus Metrics set as global variables
X = Gauge('some_value', 'some_description', ['label1', 'label2']
Y = Gauge('some_value', 'some_description', ['label1', 'label2']
Z = Gauge('some_value', 'some_description', ['label1', 'label2']

...

    # Iterate through list of strings
    for measurement in MEASUREMENTS:                                    
        metric = getattr(some_status, measurement)  # Will be an integer                                    
        upper_measurement = measurement.upper()     # Will equal the global variable name                                 
        [?UPPER_MEASUREMENT?].labels(label1=value_P1, label_2=value).set(metric)  # This is where I need to reference the global variable name

实际上是这样的:

[?UPPER_MEASUREMENT?].labels(label1=value_P1, label_2=value).set(metric)

需要:

X.labels(label1=value_P1, label_2=value).set(metric)

我试过了:

upper_measurement.labels(label1=value_P1, label_2=value).set(metric)

但是当然这会导致错误,因为它是一个字符串:

Error: 'str' object has no attribute 'labels'

不太确定从这里去哪里。我可以只写一个丑陋的大块来设置每个指标,但如果可能的话我宁愿避免这样做。

在字典中定义您的指标:

METRICS = {
    key: Gauge('some_value', 'some_description', ['label1', 'label2']) 
    for key in ['x', 'y', 'z']
}

然后您可以通过遍历字典轻松更新所有指标:

for key, metric in METRICS.items():                                    
    metric.labels(label1=value_P1, label_2=value).set(getattr(some_status, key))

尽管我认为正确的做法应该是像其他答案所指出的那样使用字典,但如果您仍然想知道,可以使用 eval() 来做到这一点。所以,只要改变

[?UPPER_MEASUREMENT?].labels(label1=value_P1, label_2=value).set(metric)

eval(upper_measurement).labels(label1=value_P1, label_2=value).set(metric)

应该可以。请注意,如果您从某些输入中获取 MEASUREMENTS 列表中的元素,但在使用 eval() 之前无法对其进行清理,因为它可能会 运行 危险代码。