Python:如何创建对引用的引用?

时间:2010-05-17 02:14:41

标签: python reference stdout

我传统上是Perl和C ++程序员,如果我误解了一些关于Python的小事,请提前道歉!

我想创建一个引用的引用。 咦?好。 Python中的所有对象实际上都是对真实对象的引用。 那么,我该如何创建对此引用的引用?

为什么我需要/想要这个?我重写sys.stdout和sys.stderr来创建一个日志库。我想要一个(二级)引用sys.stdout。

如果我可以创建对引用的引用,那么我可以创建一个通用的记录器类,其中 init 函数接收对将被覆盖的文件句柄引用的引用,例如,sys.stdout或者sys.stderr。目前,我必须对这两个值进行硬编码。

干杯, 凯文

5 个答案:

答案 0 :(得分:6)

比说起来更容易:

ostream = sys.stdout
print >> ostream, 'hi mom!'
ostream = sys.stderr
print >> ostream, 'hi mom!'
ostream = open('mylog.txt', 'a')
...

当你有更多的Python时,看看标准logging module

这个答案是基于从问题的层面推测真正需要的东西。 Python中不需要引用引用的概念,如果需要,可以通过列表或字典进行多路复用:

outputs = [sys.stderr, my_open_file_object_which_is_really_a_reference]
print >> outputs[0], 'hi dad!'
outputs = {'terminal': sys.stderr, 'logfile': file_object}
print >> outputs['logfile'], 'goodbye world!'

等等。

答案 1 :(得分:1)

您无法在python中创建对引用的引用。但是,您可以使用stderr等方法覆盖自定义类的stdoutwrite文件,以允许您自己的日志记录系统:

import sys

class MyLogger:
    def __init__(self, f):
        self.f = f

    def __getattr__(self, name):
        # forward e.g. flush() calls to the original file
        return getattr(self.f, name)

    def write(self, data):
        # log the data here!
        # ...

        # And write to the original file
        self.f.write(data)

sys.stdout = MyLogger(sys.stdout)
sys.stderr = MyLogger(sys.stderr)

答案 2 :(得分:1)

正如其他答案所说,python中没有真正的“引用引用”,但有几种方法可以获得几乎相同的效果:

>>> reference1 = "Some Data"
>>> reference2 = (reference1,)
>>> def f(data):
    print data

>>> f(reference2)
('Some Data',)
>>> f(*reference2)
Some Data

答案 3 :(得分:0)

这不可能。将所需属性作为字符串传递,并使用getattr()setattr()

答案 4 :(得分:0)

首先,已经有一个logging模块,所以你可能应该只使用它。其次,虽然不存在对引用的引用,但您可以通过包装器或函数实现该间接。例如,如果要创建用于分配对象的getter和setter函数,例如:

 class StdOutWrapper(object):
      def __init__(self):
          self.original = sys.stdout

      @property
      def value(self):
          return sys.stdout

      @value.setter
      def value(self,val):
          sys.stdout = val

然后,您可以将此对象的实例传递给记录器以分配/取消引用sys.stdout。