------ begin types1.py -----
from types import *
class C(object):
def m(self,x): return x*x
assert type(m) is FunctionType
print 'type of m inside its class:',type(m)
print 'type of C.m:', type(C.m)
assert type(C.m) is MethodType
------ end types1.py -----
The output is
type of m inside its class: <type 'function'>
type of C.m: <type 'instance method'>
i.e. the same object is seen as a function inside the class scope and as an
instance method outside the class scope. To me, this fact was quite surprising,
I don't like to have a changing type depending on the context. Maybe a unique
'function' type for both functions and methods would have been a simpler
solution.
In any case, this not such a big problem. However, consider the following
script, where static methods appear:
------ begin types2.py -----
from types import *
class C(object):
def m(self,x): return x*x
m=staticmethod(m)
#assert type(m) is ?????
print 'type of m inside its class:',type(m)
print 'type of C.m:', type(C.m)
assert type(C.m) is MethodType
------ end types2.py -----
The output of this script is
type of m inside its class: <type 'staticmethod'>
type of C.m: <type 'function'>
Now, C.m is no more an instance method, but it is a function (I understand
the logic in that), whereas the type of m is ?????
By ????? I mean that in the types modules there is no StaticMethodType,
I couldn't find any correct assertion for the type of m !
According to the documentation in types the following names are defined:
NoneType
TypeType
IntType
LongType
FloatType
ComplexType
StringType
UnicodeType
TupleType
ListType
DictType
DictionaryType
FunctionType
LambdaType
GeneratorType
CodeType
ClassType
InstanceType
MethodType
UnboundMethodType
BuiltinFunctionType
BuiltinMethodType
ModuleType
FileType
XRangeType
SliceType
EllipsisType
TracebackType
FrameType
BufferType
StringTypes
There is no StaticMethodType. At the best, this in inconsistent with the
output of type(m) when invoked in its class. I am looking forward for
reactions and comments, yours
--
Michele Simionato - Dept. of Physics and Astronomy
210 Allen Hall Pittsburgh PA 15260 U.S.A.
Phone: 001-412-624-9041 Fax: 001-412-624-9163
Home-page: http://www.phyast.pitt.edu/~micheles/
> The output is
>
> type of m inside its class: <type 'function'>
> type of C.m: <type 'instance method'>
>
> i.e. the same object is seen as a function inside the class scope
and as an
> instance method outside the class scope. To me, this fact was quite
surprising,
> I don't like to have a changing type depending on the context.
Does the following 'changing type' surprise or bother you?
>>> a=1
>>> type(a)
<type 'int'>
>>> a=[a]
>>> type(a)
<type 'list'>
Your problem is your preconception/misunderstanding of class
construction and attribute access. Its somewhat baroque. Using id()
reveals the folowing:
>>> class demo:
... def f(): pass
... print id(f), type(f)
...
7958288 <type 'function'>
>>> print id(demo.f), type(demo.f)
7716912 <type 'instance method'>
The name 'f' is *not* (bound to) the same object in the two contexts,
any more than 'a' is in my snippet above (where the rebinding is more
obvious). When a class statement is executed, the body (code) is
executed first, in a new namespace, *before* the class object exists.
Then the class name, bases tuple, and new namespace are passed as
arguments to the class constructor (its metatype or metaclass). At
some point, the function is wrapped with an instance method object,
just as I wrapped an int with a list. Introspecting just a bit more
reveals:
>>> dir(demo.f)
[...<standard attributes>... 'im_class', 'im_func', 'im_self']
>> id(demo.f.im_func), type(demo.f.im_func)
(7958288, <type 'function'>) # ie, this is original function
>>> demo == demo.f.im_class
1 #ie, method knows what class its a method of: it is not just a
function
# im_self is None here, but see below
At some point, its as if the following is done:
demo.f = instance_method(demo,f,None/instance)
But when?
>>> demo.__dict__['f']
<function f at 0x00796F10>
>>> 0x00796F10
7958288 #same as before
>>> print id(demo.f), type(demo.f)
7905904 <type 'instance method'> # new id!
>>> demo.f
<unbound method demo.f>
>>> d=demo()
>>> print id(d.f),type(d.f),d.f
7905904 <type 'instance method'> # id same here, not always
>>> d.f
<bound method demo.f of <__main__.demo instance at 0x00794D00>>
>>> d.f.im_self
<__main__.demo instance at 0x00794D00>
So the rebinding happens magically upon access, with im_self being set
or not depending on the access path (via class or instance), and with
__repr__ also being slightly different.
Terry J. Reedy
It's not the same object, though. When you access m in the class
scope, it's just a function, as you defined it.
However, when you write C.m, the class does not return the m you
defined. Instead, it returns a completely different object of type
instancemethod. The instancemethod object holds a reference to the
actual function m. When the instance method is called, calls the
actual function m with the appropriate self argument.
[snip]
> Now, C.m is no more an instance method, but it is a function (I understand
> the logic in that), whereas the type of m is ?????
> By ????? I mean that in the types modules there is no StaticMethodType,
> I couldn't find any correct assertion for the type of m !
> According to the documentation in types the following names are defined:
>
[snip]
>
> There is no StaticMethodType. At the best, this in inconsistent with the
> output of type(m) when invoked in its class. I am looking forward for
> reactions and comments, yours
Maybe it should.
But, IIRC, the language designers are trying to phase out the types
module. A lot of built in types (those with constructors, anyways)
have built in symbols that serve as name of the type. So, instead of
using IntType, you should use int. Instead of StringType, you should
use str. Instead of FileType, you should use file.
For static methods, you can use staticmethod.
And one other thing: a lot of people, myself included, believe that
using types explicitly can defeat the dynamicism of Python, which is
what makes Python so great.
--
CARL BANKS
> i.e. the same object is seen as a function inside the class scope and
> as an
> instance method outside the class scope. To me, this fact was quite
> surprising,
> I don't like to have a changing type depending on the context. Maybe a
> unique
> 'function' type for both functions and methods would have been a
> simpler
> solution.
But they're not the same. Remember that first "self" argument;
functions and methods are handled differently, so a distinction needs to
be made.
--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, USA / 37 20 N 121 53 W / &tSftDotIotE
/ \ Substance is one of the greatest of our illusions.
\__/ Sir Arthur Eddington
The laws list / http://www.alcyone.com/max/physics/laws/
Laws, rules, principles, effects, paradoxes, etc. in physics.
I see you already have received pretty complete answers, but here is
your code with the correct 'assert' statement
~~~
import types
class C(object):
def m(self,x): return x*x
m=staticmethod(m)
assert type(m) is staticmethod
print 'type of m inside its class: %r' % (type(m))
assert type(C.m) is types.FunctionType
print 'type of C.m: %r', (type(C.m))
~~~
I agree with Carl Banks, the less type checking your Python code does,
the better. Python has very fluid types and classes; methods and
attributes can be added to a class or an instance anytime during run
time. The "Pythonic" thing to do is to press ahead without type
checking, catching any errors from missing attributes or methods with
"try: except:"
Manuel
IIUC type(object) doesn't return type of the object, as we
all thought and as is written everywhere. The underlying
object is unique and can have only one type (and it has not
a name, since it's just some thing in memory).
type(object) in fact returns type of the reference `object'
to the unnamed object, and this is of course contextually
dependent.
OTOH having something NOT contextually dependent would be
nice.
Yeti
Huh? As I understand and perceive by experiment, yes it does.
>>> a=1
>>> at=type(a)
>>> at
<type 'int'>
>>> type(at)
<type 'type'>
As far as I can tell, type(object) returns the instance of the type
type that is the type of the object. Or did you mean something else?
> The underlying
> object is unique and can have only one type (and it has not
> a name, since it's just some thing in memory).
If you are saying that there is only one instance of type type for
each type (and we would not want more), you are correct.
>>> id(type(a))
504009944
>>> id(type(2))
504009944
>>> type(int)
<type 'type'>
>>> id(int)
504009944
> type(object) in fact returns type of the reference `object'
> to the unnamed object, and this is of course contextually
> dependent.
I am not sure what you are saying above. However, except for possible
complications introduced by new style class or anything I have
forgotten about, the type of an object is fixed at creation (along
with its id). There is no context dependence at all.
Terry J. Reedy
> But, IIRC, the language designers are trying to phase out the types
> module. A lot of built in types (those with constructors, anyways)
> have built in symbols that serve as name of the type. So, instead of
> using IntType, you should use int. Instead of StringType, you should
> use str. Instead of FileType, you should use file.
> For static methods, you can use staticmethod.
It is nice to know, but where is it documented ?
I was mislead from the standard documentation. When you look for the
builtin-in function "type", you obtain
type(object)
Return the type of an object. The return value is a type object.
The standard module types defines names for all built-in types.
For instance:
>>> import types
>>> if type(x) == types.StringType: print "It's a string"
If really the types module has to be deprecated (which I now think it
would be a good idea) the example should be changed to
>>> if type(x) is str: print "It's a string"
which is much much better. Are really there plans to deprecated the types
module and will be the documentation changed for Python 2.3 ?
> I was mislead from the standard documentation.
Poor gullible fool :) Seriously, this looks quite bad.
> When you look for the builtin-in function "type", you obtain
>
> type(object)
> Return the type of an object. The return value is a type object.
> The standard module types defines names for all built-in types.
> For instance:
>
> >>> import types
> >>> if type(x) == types.StringType: print "It's a string"
Oh dear, that's wrong on so many levels...
> If really the types module has to be deprecated (which I now think it
> would be a good idea) the example should be changed to
>
> >>> if type(x) is str: print "It's a string"
>
> which is much much better.
Of course, the way to write that is
>>> if isinstance(x, str): print "It's not a moose!"
but that doesn't involve the type builtin...
> Are really there plans to deprecated the types
> module
Unlikely. You shouldn't use it for things like StringType, but for
things like TracebackType there's nowhere else to go.
> and will be the documentation changed for Python 2.3 ?
I hope so. Filing a bug report would make it more likely, I guess.
Cheers,
M.
--
The ultimate laziness is not using Perl. That saves you so much
work you wouldn't believe it if you had never tried it.
-- Erik Naggum, comp.lang.lisp
> On Wed, Dec 11, 2002 at 01:05:53PM -0800, Erik Max Francis wrote:
>> Michele Simionato wrote:
>>
>>> i.e. the same object is seen as a function inside the class scope and
>>> as an
>>> instance method outside the class scope. To me, this fact was quite
>>> surprising,
>>> I don't like to have a changing type depending on the context. Maybe
>>> a
>>> unique
>>> 'function' type for both functions and methods would have been a
>>> simpler
>>> solution.
>>
>> But they're not the same. Remember that first "self" argument;
>> functions and methods are handled differently, so a distinction needs
>> to
>> be made.
>
> IIUC type(object) doesn't return type of the object, as we
> all thought and as is written everywhere. The underlying
> object is unique and can have only one type (and it has not
> a name, since it's just some thing in memory).
type(value) does return the type of the object, the examples of
the OP just print the types of different objects:
class Foo:
def bar(self):
pass
print id(bar), type(bar)
print id(Foo.bar), type(Foo.bar)
On my system this prints:
1118848 <type 'function'>
1155808 <type 'instance method'>
When class Foo is constructed the function object 'bar' is converted to
an instancemethod object.
Ronald
Okay, I have filed a documentation bug report, even it is not really a
bug but a request of documentation improving.
M.
Cool. Those things count as bugs in our world.
I should try to have a docco bugsplatting day sometime soonish.
Cheers,
M.
--
MARVIN: Oh dear, I think you'll find reality's on the blink again.
-- The Hitch-Hikers Guide to the Galaxy, Episode 12
Thank you Michele for helping us debug our process.
Laura
> mi...@pitt.edu (Michele Simionato) writes:
>
> > Michael Hudson <m...@python.net> wrote in message news:<7h38yyvgto8.fsf@pc15
> 0.maths.bris.ac.uk>...
> > > mi...@pitt.edu (Michele Simionato) writes:
> > > > Are really there plans to deprecated the types
> > > > module
> > >
> > > Unlikely. You shouldn't use it for things like StringType, but for
> > > things like TracebackType there's nowhere else to go.
> > >
> > > > and will be the documentation changed for Python 2.3 ?
> > >
> > > I hope so. Filing a bug report would make it more likely, I guess.
> > >
> > > Cheers,
> > > M.
> >
> > Okay, I have filed a documentation bug report, even it is not really a
> > bug but a request of documentation improving.
>
> Cool. Those things count as bugs in our world.
>
> I should try to have a docco bugsplatting day sometime soonish.
>
> Cheers,
> M.
>
> --
> MARVIN: Oh dear, I think you'll find reality's on the blink again.
> -- The Hitch-Hikers Guide to the Galaxy, Episode 12