Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 变量的符号链接_Python_Python 3.x - Fatal编程技术网

Python 变量的符号链接

Python 变量的符号链接,python,python-3.x,Python,Python 3.x,我正在做一个程序,我想不时报告特定变量的状态,但是,我不一定知道我需要哪些变量。我所研究的其他程序(在C++中)使用注册系统,其中感兴趣的变量向中央输出处理器注册一次,然后当需要报告程序状态时,中央模块从输出变量收集数据并写入输出文件。所以,程序流程应该是这样的 示例MyModule.py from OutputProcessor import OutputProcessor class MyClass(): def __init__(self): op = Out

我正在做一个程序,我想不时报告特定变量的状态,但是,我不一定知道我需要哪些变量。我所研究的其他程序(在C++中)使用注册系统,其中感兴趣的变量向中央输出处理器注册一次,然后当需要报告程序状态时,中央模块从输出变量收集数据并写入输出文件。所以,程序流程应该是这样的

示例
MyModule.py

from OutputProcessor import OutputProcessor


class MyClass():

    def __init__(self):
        op = OutputProcessor()

        # variable I want to report
        self.foo = None

        # register with output processor
        op.register_output_variable(self.foo, "Foo")

    def calc_foo(self, bar, rand):
        self.foo = bar ** rand
class OutputProcessor(object):
    # list or dict object containing the name and link information to variables of interest
    output_vars_data = []

    def __init__(self):
        pass

    def register_output_variable(self, var, name):
        OutputProcessor.output_vars_data.append({"link address": id(var), "name": name})

    def report_output(self):
        for data in OutputProcessor.output_vars_data:
            self.write_to_output_file(data)

    def write_to_output_file(self, data):
        # write all of the data to the output file here
        pass
import random

from MyClass import MyClass
from OutputProcessor import OutputProcessor as OP

if __name__ == "__main__":

    cls_instance = MyClass()

    for i in range(100):
        cls_instance.calc_foo(i, random.randint(1, 10))
        OP().report_output()
示例
OutputProcessor.py

from OutputProcessor import OutputProcessor


class MyClass():

    def __init__(self):
        op = OutputProcessor()

        # variable I want to report
        self.foo = None

        # register with output processor
        op.register_output_variable(self.foo, "Foo")

    def calc_foo(self, bar, rand):
        self.foo = bar ** rand
class OutputProcessor(object):
    # list or dict object containing the name and link information to variables of interest
    output_vars_data = []

    def __init__(self):
        pass

    def register_output_variable(self, var, name):
        OutputProcessor.output_vars_data.append({"link address": id(var), "name": name})

    def report_output(self):
        for data in OutputProcessor.output_vars_data:
            self.write_to_output_file(data)

    def write_to_output_file(self, data):
        # write all of the data to the output file here
        pass
import random

from MyClass import MyClass
from OutputProcessor import OutputProcessor as OP

if __name__ == "__main__":

    cls_instance = MyClass()

    for i in range(100):
        cls_instance.calc_foo(i, random.randint(1, 10))
        OP().report_output()
示例
Main.py

from OutputProcessor import OutputProcessor


class MyClass():

    def __init__(self):
        op = OutputProcessor()

        # variable I want to report
        self.foo = None

        # register with output processor
        op.register_output_variable(self.foo, "Foo")

    def calc_foo(self, bar, rand):
        self.foo = bar ** rand
class OutputProcessor(object):
    # list or dict object containing the name and link information to variables of interest
    output_vars_data = []

    def __init__(self):
        pass

    def register_output_variable(self, var, name):
        OutputProcessor.output_vars_data.append({"link address": id(var), "name": name})

    def report_output(self):
        for data in OutputProcessor.output_vars_data:
            self.write_to_output_file(data)

    def write_to_output_file(self, data):
        # write all of the data to the output file here
        pass
import random

from MyClass import MyClass
from OutputProcessor import OutputProcessor as OP

if __name__ == "__main__":

    cls_instance = MyClass()

    for i in range(100):
        cls_instance.calc_foo(i, random.randint(1, 10))
        OP().report_output()
我的第一个问题:这是可能的,还是可行的?第二,如果是这样,我将如何着手这样做?将会有一些细微差别需要处理,比如如何处理同一类的多个实例报告同一个变量,但这似乎是个小问题。有没有一种方法可以实现这一点,使我总是得到变量的当前值,而不仅仅是它的旧副本


有什么想法或建议吗?

除了代码中的范围问题之外,还有一个问题需要记住。Python通过将名称绑定到引用来完成所有工作。您感兴趣的是获得分配给名称的值,而不是它在注册时可能已绑定到的引用。这有点像C和C++中的一个pto to a指针。 要跟踪任意名称,还需要跟踪它们的封闭名称空间。这样,您就可以使用通用函数
getattr
获取您姓名的最新值。命名空间可以是任何实例(模块和类也是实例)

您的注册方法需要跟踪包含感兴趣的名称、名称本身以及要将其显示为的密钥的对象:

op.register_output_variable(self, 'foo', "Foo")
manager类可以将值存储在字典中。我建议使用
tuple
collections.namedtuple
来保存“指针”,而不是嵌套字典:

当您输出变量时,执行如下操作

for key, spec in self.output_vars_data.items():
    print(key, '=', getattr(*spec))
这为您提供了一种通过名称而不是引用来引用对象属性的方法。如果设置
x.a=1
,注册
x.a
,然后执行
x.a+=1
,则希望获得
2
作为值。重要的是要记住,
x.a
将绑定到不同的引用,因为整数在Python中是不可变的。通过将
x
注册为名称空间,将
'a'
注册为名称,可以完全绕过此问题

您可以通过添加一个方法来注册可索引元素(如列表中的元素和字典中的值)来进一步推广。您将注册实例和索引/键,而不是实例和属性名。查看
operator.attrgetter
operator.itemgetter
了解更多想法


这只是一个宽泛的建议。它没有解决您正在使用的静态、类和实例名称空间不一致的问题。

您将calc_foo定义为类的方法,而不是纯函数。你不能这样称呼它。但是您可以将其定义为
@staticmethod
,并像使用
MyClass.calc\u foo()
“从MyClass导入calc\u foo”一样使用它。这不可能始终通过引用导入methodPython works。当您使用不可变类时,这仍然会有问题。请查看操作员模块中的attrgetter。@PM2Ring yes,谢谢。我希望现在更清楚了。本质上,我希望能够用我的register_var函数注册任意成员变量,然后在程序运行期间的任何时候报告这些变量的状态。正如Mad Physician所解释的,在Python中做这种事情并不容易。Python变量不像C++变量,数据模型非常不同。您可能会发现这篇文章很有帮助:,它是由资深的Ned Batchelder撰写的。谢谢您的评论和建议。我将根据您提供的内容在此基础上进行更多的原型设计。目前,我认为我不需要在列表或字典中注册元素。关于范围界定问题,我显然“不知道我不知道什么”。我自己很少接受过正式的CS或编程培训,如果能就如何改进我的示例提出建议,我将不胜感激,这样我就能更好地理解应该如何做。