Python - 对象属性分配失败

时间:2013-03-07 19:19:24

标签: python

我的问题是,在此行之后:-> self.__serverUrl = serverUrl

为什么会这样?: *** AttributeError: Client instance has no attribute '__serverUrl'

详情

我正在使用Beatbox与Salesforce进行交互,我收到了错误

*** AttributeError: Client instance has no attribute '_Client__serverUrl'

我想知道为什么这个字段在设置之前被访问了,所以我添加pdb.set_trace()以为我能找到一些答案。这就是我所看到的(注释第67行):

(Pdb)
--Call--
> /app/env/local/lib/python2.7/site-packages/beatbox/_beatbox.py(65)useSession()
-> def useSession(self, sessionId, serverUrl):
(Pdb) l
 64         # initialize from an existing sessionId & serverUrl, useful if we're being launched via a custom link
 65  ->     def useSession(self, sessionId, serverUrl):
 66             self.sessionId = sessionId
 67             self.__serverUrl = serverUrl
 68             (scheme, host, path, params, query, frag) = urlparse(self.__serverUrl)
 69             self.__conn = makeConnection(scheme, host)
 70

我检查serverUrl的值,一切都是应该的。然后我进入第67行,让它执行并认为serverUrl的值将在self.__serverUrl中。显然不是......

> /app/env/local/lib/python2.7/site-packages/beatbox/_beatbox.py(67)useSession()
-> self.__serverUrl = serverUrl
(Pdb) n
> /app/env/local/lib/python2.7/site-packages/beatbox/_beatbox.py(68)useSession()
-> (scheme, host, path, params, query, frag) = urlparse(self.__serverUrl)
(Pdb) self.__serverUrl
*** AttributeError: Client instance has no attribute '__serverUrl'

这里发生了什么!?这不应该发生。看起来这项任务正在悄然失败。为什么这里没有分配这个值?

来源

我正在使用的源代码是here

我创建了一个beatbox客户端并登录

svc = PythonClient()
svc.login(username, password)

这将调用python_client.Client的登录方法。 python_client.Client.login调用它的超类_beatbox.Client的登录方法,如下所示:

class Client:
    def __init__(self, serverUrl=None):
       ...

    # login, the serverUrl and sessionId are automatically handled, returns the loginResult structure       
    def login(self, username, password):
        lr = LoginRequest(self.serverUrl, username, password).post()
        self.useSession(str(lr[_tPartnerNS.sessionId]), str(lr[_tPartnerNS.serverUrl]))
        return lr

    # initialize from an existing sessionId & serverUrl, useful if we're being launched via a custom link   
    def useSession(self, sessionId, serverUrl):
        self.sessionId = sessionId
        self.__serverUrl = serverUrl
        (scheme, host, path, params, query, frag) = urlparse(self.__serverUrl)
        self.__conn = makeConnection(scheme, host)

分配发生在_beatbox.Client.useSession中,它是对象svc的超类

1 个答案:

答案 0 :(得分:2)

当它们出现在类范围内时,以双下划线为前缀的名称(并且没有后缀为双下划线)是 mangled 。名称因前缀_<classname>而受损。

如果在全局范围内声明一个设置双下划线前缀名称的函数,则会设置错误的属性,因为不会发生名称修改。如果在派生类中声明这样的函数,您还将访问错误的属性,因为名称修改将添加派生类的名称而不是基类(因此,名称修改实现了弱形式的私有属性)。

如果子类需要访问属性或使用属性,那么正确的做法是完全避免名称损坏。如果你无法避免,你将不得不使用这个kludge:

self._Client__serverUrl = ...