0

私の質問は、この行の後です: -> 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'

ここで何が起きてるの!?これは起こるべきではありません。割り当ては静かに失敗しているようです。この値がここに割り当てられていないのはなぜですか?

起源

私が取り組んでいるソースコードはここにあります

Beatbox クライアントを作成してログインする

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

これは python_client.Client の login メソッドを呼び出します。python_client.Client.login は、そのスーパークラス _beatbox.Client の login メソッドを呼び出します。これは次のようになります。

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

4

1 に答える 1

2

2 つのアンダースコアがプレフィックスとして付けられた (および 2 つのアンダースコアがサフィックスとして付けられていない) 名前は、クラス スコープ内に現れるとマングルされます。名前は接頭辞 によってマングルされ_<classname>ます。

アンダースコアが 2 つ付いた名前を設定する関数をグローバル スコープで宣言すると、名前のマングリングが発生しないため、間違った属性が設定されます。派生クラスでそのような関数を宣言すると、名前マングリングによって基底クラスではなく派生クラスの名前が追加されるため、間違った属性にアクセスすることになります (したがって、名前マングリングは弱い形式のプライベート属性を実装します)。

サブクラスが属性にアクセスする必要がある場合、またはプロパティを使用する必要がある場合は、名前マングリングを完全に回避することが適切です。避けられない場合は、次のクラッジを使用する必要があります。

self._Client__serverUrl = ...
于 2013-03-07T19:22:20.783 に答える