简体   繁体   English

如何在 Python 3 的内部类中动态初始化对象?

[英]How to dynamically initialize an object within an inner class in Python 3?

I am leveraging the SeriesHelper object of InfluxDB library( please have a look at https://influxdb-python.readthedocs.io/en/latest/examples.html#tutorials-serieshelper ) to push set of data points to InfluxDB.我正在利用 InfluxDB 库的 SeriesHelper 对象(请查看https://influxdb-python.readthedocs.io/en/latest/examples.html#tutorials-serieshelper )将一组数据点推送到 InfluxDB。 The SeriesHelper class has to be inherited and the child class needs to initialize various objects as its meta attributes, so as to override the default values of the objects in the Parent class. SeriesHelper类需要继承,子类需要初始化各种对象作为其元属性,以覆盖Parent 类中对象的默认值。

Actual code实际代码

class MySeriesHelper(SeriesHelper):
    """Instantiate SeriesHelper to write points to the backend."""

    class Meta:
        """Meta class stores time series helper configuration."""
        client = myclient
        series_name = 'rf_results'
        fields = ['some_stat', 'other_stat']
        tags = ['server_name']
        bulk_size = 5
        autocommit = True

Here the 'series_name' object is initialized(hard-coded) right before it is ran as a script.这里“series_name”对象在作为脚本运行之前被初始化(硬编码)。 My use case is to initialize 'series_name' based on the runtime arguments that are passed to this script.我的用例是根据传递给此脚本的运行时参数初始化“series_name” I tried by defining a global variable whose value is providing at runtime and assigning that global variable to the 'series_name' like the below one, but in vain.我尝试定义一个全局变量,其值在运行时提供,并将该全局变量分配给“series_name”,如下所示,但徒劳无功。

Problematic code有问题的代码

series_configured = None
class MySeriesHelper(SeriesHelper):
    """Instantiate SeriesHelper to write points to the backend."""

    class Meta:
        """Meta class stores time series helper configuration."""
        client = myclient
        series_name = series_configured
        fields = ['some_stat', 'other_stat']
        tags = ['server_name']
        bulk_size = 5
        autocommit = True

def main():
    global series_configured
    series_configured = args.series_name

    MySeriesHelper(server_name='server_A', some_stat='Master server', other_stat='Controller')
    MySeriesHelper.commit()

if __name__ == "__main__":
    parser = argparse.ArgumentParser()

    parser.add_argument("--series_name", dest='series_name', 
                        help="The measurement to be used for storing the data points",required=True)
    args = parser.parse_args()
    main()

Error seen while running is运行时看到的错误是

'NoneType' object has no attribute 'format' 'NoneType' 对象没有属性 'format'

It infers that the object 'series_name' is not initialized with a value.它推断对象“series_name”没有用值初始化。 Is there any way of properly initializing it ?有什么方法可以正确初始化它吗?

When the python interpreter go over the code (line by line) it define all the classes static variable.python 解释器检查代码(逐行)时,它定义了所有类静态变量。 It's set static variable before you create an instance from a class.在从类创建实例之前,它已设置为静态变量。 That mean when you reach the point of:这意味着当您到达以下点时:

autocommit = True

The value of series_name is already set to None (because that is the value of series_configured at the point). series_name的值已经设置为None (因为这是当时series_configured的值)。

The following example show that the static variable are already set before I created an instance:以下示例显示在我创建实例之前已经设置了静态变量:

>>> series_configured = None
>>> class MySeriesHelper:
    """Instantiate SeriesHelper to write points to the backend."""

    class Meta:
        """Meta class stores time series helper configuration."""
        series_name = series_configured
        fields = ['some_stat', 'other_stat']
        tags = ['server_name']
        bulk_size = 5
        autocommit = True

>>> print(MySeriesHelper.Meta.series_name)
None

If you want to change the Meta.series_configured static variable you will have to set it after the series_configured change its content.如果要更改Meta.series_configured静态变量,则必须在series_configured更改其内容后进行设置。

Try the following main.尝试以下主要。

def main():
    global series_configured
    series_configured = args.series_name
    # The following line will set the variable at the inner Meta class.
    MySeriesHelper.Meta.series_name = series_configured

    MySeriesHelper(server_name='server_A', some_stat='Master server', other_stat='Controller')
    MySeriesHelper.commit()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM