self 仅在 eval 的范围内,当 self 在同一 scope/function 中预先被引用时

self only in scope for eval when self is referred to beforehand in same scope/function

在下面的代码中 eval 调用成功:

from zeep import Client
from zeep import xsd
from zeep.plugins import HistoryPlugin

class TrainAPI:
    def __init__(self,LDB_TOKEN):
        if LDB_TOKEN == '':
            raise Exception("Please configure your OpenLDBWS token")
        WSDL = 'http://lite.realtime.nationalrail.co.uk/OpenLDBWS/wsdl.aspx?ver=2017-10-01'
        history = HistoryPlugin()
        self.client = Client(wsdl=WSDL, plugins=[history])

        header = xsd.Element(
            '{http://thalesgroup.com/RTTI/2013-11-28/Token/types}AccessToken',
            xsd.ComplexType([
                xsd.Element(
                    '{http://thalesgroup.com/RTTI/2013-11-28/Token/types}TokenValue',
                    xsd.String()),
            ])
        )
        self.header_value = header(TokenValue=LDB_TOKEN)
        self.token = LDB_TOKEN
        return

    def __getattr__(self, action):
        def method(*args,**kwargs):
            print(action,args,kwargs)
            print(self)
            return eval(f"self.client.service.{action}(*args,**kwargs, _soapheaders=[self.header_value])")
        return method

但是,如果删除 print(self) 行,则会抛出以下错误:

File "C:/Users/-/Documents/-/main.py", line 32, in method
    return eval(f"self.client.service.{action}(*args,**kwargs, _soapheaders=[self.header_value])")
  File "<string>", line 1, in <module>
NameError: name 'self' is not defined

抱歉,如果我遗漏了一些明显的东西,但我的问题是:为什么 self 没有定义,除非我事先在 [=18] 中调用引用它的东西(例如 print(self)) =] 功能? 看起来很复杂,因为回溯最终指的是 <string>...

的第 1 行

编辑:尝试这个也returns一个错误:

def __getattr__(self, action):
        def method(*args,**kwargs):
            print(action,args,kwargs)
            print(f"self.client.service.{action}(*args,**kwargs, _soapheaders=[self.header_value])")
            return eval(f"self.client.service.{action}(*args,**kwargs, _soapheaders=[self.header_value])")
        return method

可能我不明白范围或格式字符串是如何工作的。

原因有点深入 python 的工作原理,如果你真的想要,我可以告诉你,但要解决你的实际问题,答案是尽可能避免 eval,因为通常有更好的方法方法。在这种情况下:

method = getattr(self.client.service, action)
return method(*args,**kwargs, _soapheaders=[self.header_value])