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

发布于 2024-09-01 18:02:39 字数 366 浏览 7 评论 0原文

我传统上是一名 Perl 和 C++ 程序员,所以如果我误解了有关 Python 的一些琐碎的事情,请提前道歉!

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

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

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

干杯, 凯文

I am traditionally a Perl and C++ programmer, so apologies in advance if I am misunderstanding something trivial about Python!

I would like to create a reference to a reference.
Huh? Ok. All objects in Python are actually references to the real object.
So, how do I create a reference to this reference?

Why do I need/want this? I am overriding sys.stdout and sys.stderr to create a logging library. I would like a (second-level) reference to sys.stdout.

If I could create a reference to a reference, then I could create a generic logger class where the init function receives a reference to a file handle reference that will be overrided, e.g., sys.stdout or sys.stderr. Currently, I must hard-code both values.

Cheers,
Kevin

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

苦妄 2024-09-08 18:02:39

做起来比说起来容易:

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

当你有更多的Python时,看看标准的日志模块在你的腰带下。

这个答案是基于从问题的层面来看真正需要什么的假设。 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!'

等等。

Easier done than said:

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

And look at the standard logging module when you have some more Python under your belt.

This answer was based on the presumption, from the level of the question, of what was really needed. The concept of a reference to a reference is not needed in Python, you can multiplex through a list or a dict if you want:

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!'

and so on.

暖心男生 2024-09-08 18:02:39

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

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)

You can't create references to references in python. You can however override the stderr and stdout files with custom classes with write etc methods to allow your own logging systems:

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)
墨离汐 2024-09-08 18:02:39

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

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

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

As the other answers say, there is no true "references of references" in python, but there are ways of getting nearly the same effect:

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

>>> f(reference2)
('Some Data',)
>>> f(*reference2)
Some Data
以为你会在 2024-09-08 18:02:39

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

This can't be done. Pass the desired attribute as a string and use getattr() and setattr().

花期渐远 2024-09-08 18:02:39

首先,已经有一个 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。

Firstly, there is already a logging module, so you probably should just use that. Secondly, while there is no such thing as a reference to a reference, you can achieve that indirection via a wrapper or function. For example, if you were to create a getter and setter function for assigning the object, like:

 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

You could then pass an instance of this object to your logger to assign/dereference sys.stdout.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文