Python 下面是对该计划的一个小澄清

Python 下面是对该计划的一个小澄清,python,Python,我从一个堆栈流线程中获取了这个示例。。 在这段代码中,正在从Logger类调用用户定义的函数write和doNothing import logging import pexpect import re # this is the method called by the pexpect object to log def _write(*args, **kwargs): content = args[0] # Ignore other params, pexpect onl

我从一个堆栈流线程中获取了这个示例。。

在这段代码中,正在从Logger类调用用户定义的函数write和doNothing

import logging
import pexpect
import re

# this is the method called by the pexpect object to log
def _write(*args, **kwargs):
    content = args[0]
    # Ignore other params, pexpect only use one arg
    if content in [' ', '', '\n', '\r', '\r\n']:
        return # don't log empty lines
    for eol in ['\r\n', '\r', '\n']:
        # remove ending EOL, the logger will add it anyway
        content = re.sub('\%s$' % eol, '', content)
    return logger.info(content) # call the logger info method with the reworked content

# our flush method
def _doNothing():
    pass

logger = logging.getLogger('foo')
hdlr = logging.FileHandler('/bar.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.INFO)

# give the logger the methods required by pexpect
logger.write = _write
logger.flush = _doNothing

p = pexpect.spawn('echo "hello world !"', logfile=logger)

logger类没有这些方法。只是想知道这些电话是怎么打的?有人能解释一下以便我能更好地理解吗?

logger.write
logger.flush
是同一模块中用户定义函数
\u write()
\u doNothing()
的简单别名。想象一个简化的场景

# User defined function
>>> def _write():
...    print 'Inside _write()'

# Sample Logger class
>>> class Logger:
...    pass

# Object of type Logger
>>> logger = Logger()

# Simply adding a new attribute 'write' to the object 'logger'
# and point to the user defined function name.
# This will create an alias.
>>> logger.write = _write
>>> logger.write()
Inside _write()

# Proof that both 'logger.write' and '_write' are indeed 
# same 
>>> id(logger.write) == id(_write)
简而言之,在
Logger
类中没有
\u write()
,但是,您仍然可以为对象创建属性并为其指定别名以引用用户定义的函数


这正是上面代码中发生的情况。

继续Pankaj的答案(这是正确的),您甚至可以使用
类型在自由函数中绑定
self
。MethodType

import types

class Foo:
    def _print(self, msg):
        print("_print(self=%s, msg='%s')" % (self, msg))

    def hello(self, name):
        self._print("Hello, %s!" % name)

def my_print(self, msg):
    print("my_print(self=%s, msg='%s')" % (self, msg))

# Normal call
foo = Foo()
foo.hello("foobar")

# Swap _print with my_print, binding it to a method so you can use `self`
foo._print = types.MethodType(my_print, foo, Foo)
foo.hello("foobar")
其中打印:

_print(self=<__main__.Foo instance at 0x7f958e772098>, msg='Hello, foobar!')
my_print(self=<__main__.Foo instance at 0x7f958e772098>, msg='Hello, foobar!')
\u打印(self=,msg='Hello,foobar!')
我的打印(self=,msg='Hello,foobar!')

我想你指的是答案吧?您应该重写您的问题以包含该代码,因为现在这不是一个独立的问题。这里的函数已经定义,只需更改记录器函数即可使用它们。是的。只是想知道用户定义的函数是如何从记录器中调用的?@csl我尝试使用自己的用户定义函数调用,但未能调用。我猜这与我不理解的这行p=pexpect.spawn('echo“hello world!”,logfile=logger)有关。你能帮我理解吗。当我有自己的函数时,我得到了以下错误msg.Traceback(上次调用):logger中第38行的文件“logger.py”。\u myOwnMethod()AttributeError:'logger'对象没有属性'\u myOwnMethod'[root@n3k-qa auto featurelib]#您需要发布无法使用的特定代码。谢谢Pankaj。。现在明白了。很高兴知道,这很有用!