On Mon, Nov 9, 2015 at 12:42 AM, BartC <b...@freeuk.com> wrote: > Sorry, you'll have to assume I'm very stupid. > > What exactly is being looked up, and in what? > > From what I can understand in your example: > > * You are calling shutil.copyfileobj with two arguments, which happen to be > instances of classes Source and Dest. > > * Let's say these are known as src and dst inside .copyfileobj. > > * .copyfileobj then calls methods src.read() dst.write(). > > * Each of these method calls has the form A.B() which seems to me to be > little different from shutil.copyfileobj(). > > So to get back to what I was saying, does this lookup involving searching > for method B in object A, and if so, does it actually do a search by name? > > (Someone mentioned a precalculated hash, of "A", or of "src" or "dst", use > used, but still, it's looking something up in a table, and a hash table > lookup I believe still requires an string compare to check if you've got the > right entry.)
The lookups I'm talking about happen pretty much anywhere. Firstly, this function: def f(): shutil.copyfileobj(src, dst) looks up the global name 'shutil' (that's one dict lookup - module globals are a dictionary), then performs an attribute lookup on the resulting object with the name 'copyfileobj', then looks up the two global names 'src' and 'dst'. In fact[1], those strings can be found in f.__code__.co_names, and the byte-code identifies them by their indices in that tuple. These are str objects (note that this means they can be any legal Unicode string; "шутил.цопыфилеобй(срц, дст)" is just as valid), and their hashes will normally be precomputed to save time. Now, things are a bit different with function-locals; the compiler always knows which names they are, and it can compile things differently. Compare: def f(src): shutil.copyfileobj(src, dst) Instead of looking up a global name 'src', this now looks up a local name. They're identified by slot positions, so the compiler simply knows that "src" is in slot #0, and instead of looking anything up, simply says "load the thing in slot #0". There can also be other levels of indirection, such as __getattr__ and __getattribute__, which affect how stuff gets looked up. But otherwise, name lookups generally involve poking a dict with a string and taking what comes back (possibly replacing KeyError with NameError or AttributeError as the case may be). ChrisA [1] Assuming we're using CPython, or something which uses the same byte-code; this is NOT a language requirement - none of this is. -- https://mail.python.org/mailman/listinfo/python-list