Field Population (ReviewBoard code)
-
21-12-2019 - |
Вопрос
I'm am making custom modifications to ReviewBoard (RBtools); however, I can't seem to understand what Python is doing implicitly at this step.
I am trying to understand where ReviewBoardServer
sets its value for self.info.path
.
I stepped through the debugger and traced it to the method check_api_version
on the line
self.root_resource = root_resource
Prior to this statement, we have self.info
as None
, but it quickly changes to an SVNRepositoryInfo
after the line above.
The line above does not set the class field of self.info
in that line. I am guessing that Python is doing something under the hood that allows it to populate self._info
by setting self.root_resource
? Is this correct? If so, where would I find more information about this?
For reference the init method looks like:
185 class ReviewBoardServer(object):
186 """
187 An instance of a Review Board server.
188 """
189 def __init__(self, url, info, cookie_file):
190 self.url = url
191 if self.url[-1] != '/':
192 self.url += '/'
193 self._info = info
194 self._server_info = None
195 self.capabilities = None
196 self.root_resource = None
197 self.deprecated_api = False
198 self.rb_version = "0.0.0.0"
199 self.cookie_file = cookie_file
200 self.cookie_jar = cookielib.MozillaCookieJar(self.cookie_file)
201 self.deprecated_api = False
202 self.root_resource = None
For reference, the specific file is hosted on Github below: https://github.com/reviewboard/rbtools/blob/release-0.4.3/rbtools/postreview.py
Решение
You can do things like that "under the hood" in Python using descriptors along with the built-inproperty()
function.
See Implementing Descriptors in the documentation for more details.
Thepostreview.py
source file has the line:
627 info = property(_get_server_info)
Which defines a__get__()
function for theReviewBoardServer
class attribute namedinfo
.
The definition of_get_server_info()
is right above that in the source:
def _get_server_info(self):
if not self._server_info:
self._server_info = self._info.find_server_repository_info(self)
return self._server_info
As you can see, whenever the value ofinfo
is retrieved, if the value ofself._server_info
isNone
, it is set to something and then its value is returned as the value of the attribute.