Post by Jim Mooney Py3.4.3winXPOkay, it appears the method in a class has its own ID, but all
instantiations of that method have identical IDs.
I'm not sure what you mean by this. *All* objects have their own ID, and
instantiations of methods *don't* have identical IDs, although it may
appear so at first glance (see further below).
py> class C:
... def method(self):
... return 23
...
py> c = C()
py> x = c.method # grab a reference to the method
py> y = c.method # and another one
py> print(id(x), id(y))
3082036364 3082100428
*But* that's actually an implementation detail. It just so happens that
the way CPython currently works, each time you look up a method you get
a new instance. Technical details are technical, and involve the
descriptor protocol, which you don't need to understand. I'm happy to go
into detail if you like, but for now let's just skip over it and just
call it "magic".
There's nothing in the language specification (that I know of) which
*promises* that x and y must be separate objects with different IDs.
The underlying function object, retrieved directly from the class
__dict__, *is* guaranteed to always give the same object:
py> a = C.__dict__['method']
py> b = C.__dict__['method']
py> print(id(a), id(b))
3083756356 3083756356
That's the way dictionaries work.
Post by Jim Mooney Py3.4.3winXPBut what happens if we
have a huge number of instantiations trying to access the identical method
at the same time?
What of it? I don't understand what you think the potential problem is.
Regardless of whether you access the method wrapper, or the underlying
function, calling it from multiple places is allowed. Each function call
is independent of the others.
Naturally, the *action* of the function may not be safe to call twice.
(It might, say, try to delete the same file twice, and the second time
you get an error because the file no longer exists.) But the function
calling infrastructure is safe to do multiple times:
len(a) # Safe to call it once.
len(b) # and still safe to call it twice
LEN = len; LEN(c) # even if you use a different name
Post by Jim Mooney Py3.4.3winXPself.data = data
print(self.data)
<function MyClass.setdata at 0x026CACD8>
In Python 3, looking up MyClass.setdata returns the underlying function
object. But in Python 2, it actually returns an "unbound method" object,
which is a wrapper around the underlying function. I mention this only
for completion, in practice it makes little or no difference.
Post by Jim Mooney Py3.4.3winXP40676568
f = MyClass()
g = MyClass()
id(f.setdata)
43576616
43576616
d = MyClass()
id(d.setdata)
43576616
You are misinterpreting what you are seeing. Python is free to reuse
IDs. CPython does re-use them, IronPython and Jython do not.
When you run this line of code:
id(f.setdata)
at least five things happen:
- Python does an attribute search for "setdata" starting with f;
- it finds the *function* f inside the class __dict__;
- because functions are descriptors ("magic"), Python creates a *method*
wrapper around the function, and returns that;
- the method gets passed to the id() function, which determines the ID
(in this case 43576616) and returns that;
- the method object is then garbage collected, which frees up the ID to
be re-used the next time you create a method.
If you did the same thing in (say) Jython, you would get very different
43
44
45
(the actual IDs may vary).
But *most of the time* none of this has the least bit of importance to
your code. Whether you get the same method object or different method
objects is more or less irrelevant to how your code works. The exception
is when you start looking at introspection functions like id(), or
testing for object identity ("is this the same object?") using `is`.
--
Steve
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor