Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #25830 > unrolled thread
| Started by | Chris Angelico <rosuav@gmail.com> |
|---|---|
| First post | 2012-07-23 08:54 +1000 |
| Last post | 2012-07-22 20:44 -0400 |
| Articles | 5 — 3 participants |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: default repr? Chris Angelico <rosuav@gmail.com> - 2012-07-23 08:54 +1000
Re: default repr? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-23 00:24 +0000
Re: default repr? Chris Angelico <rosuav@gmail.com> - 2012-07-23 10:29 +1000
Re: default repr? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-23 01:40 +0000
Re: default repr? Devin Jeanpierre <jeanpierreda@gmail.com> - 2012-07-22 20:44 -0400
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-07-23 08:54 +1000 |
| Subject | Re: default repr? |
| Message-ID | <mailman.2444.1342997643.4697.python-list@python.org> |
On Mon, Jul 23, 2012 at 8:48 AM, Dan Stromberg <drsalists@gmail.com> wrote: > If a class has defined its own __repr__ method, is there a way of getting > the default repr output for that class anyway? Methods are just functions, and you can call any method of any class with any object as its first parameter. object.__repr__(some_object) Though this mightn't work with everything. I wasn't able to paint a list as a tuple - "tuple.__repr__([1,2,3])" threw a TypeError. Oh well. There's a limit to the ways Python lets you shoot yourself in the foot. ChrisA
[toc] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2012-07-23 00:24 +0000 |
| Message-ID | <500c99d5$0$29978$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #25830 |
On Mon, 23 Jul 2012 08:54:00 +1000, Chris Angelico wrote:
> On Mon, Jul 23, 2012 at 8:48 AM, Dan Stromberg <drsalists@gmail.com>
> wrote:
>> If a class has defined its own __repr__ method, is there a way of
>> getting the default repr output for that class anyway?
If the class, call it C, is a subclass of some other class (or classes),
then there is also the repr of the parent. You can get to that by calling
parent.__repr__(instance), although there are some subtleties.
In Python 2, there are old-style or classic classes that don't inherit
from anything else. I don't believe there is any way to get the repr of a
classic class with no __repr__ method *except* from an instance with no
__repr__ method. So the answer for C below will be No:
# Python 2.x
class C:
def __repr__(self):
return "C()"
But for new-style classes in Python 2, or all classes in Python 3, the
answer is Yes. All classes inherit from object, directly or indirectly,
so you can either call the object repr or use super:
# Python 2.x or 3.x
class K(object): # inheriting from object makes it "new style"
def __repr__(self):
# but please don't do this -- see below for a better way
print(object.__repr__(self))
return "K()"
You can specify the parent class directly by name, as above, grab its
__repr__ method, and call it. But that's the wrong solution: it does not
work correctly with multiple inheritance, and even if you don't use MI
yourself, it means that nobody else can use your class for MI.
Better is to allow Python to work out which parent class you have, even
if you already know the answer and only have one parent. The dance is a
little more complex, but now you are multiple-inheritance-safe:
# Python 2.x or 3.x
class K(object):
def __repr__(self):
# this ONLY works for new-style classes
print(super(K, self).__repr__())
return "K()"
Python 3 offers some additional magic: if you don't give super() any
arguments, the compiler magically does the right thing:
# Python 3.x
class K(object): # or just "class K"
def __repr__(self):
print(super().__repr__())
return "K()"
> Methods are just functions, and you can call any method of any class
> with any object as its first parameter.
Not quite: they have to be an instance of that class.
> object.__repr__(some_object)
That will work because everything is an instance of object (apart from
classic classes in Python 2).
> Though this mightn't work with everything. I wasn't able to paint a list
> as a tuple - "tuple.__repr__([1,2,3])" threw a TypeError. Oh well.
> There's a limit to the ways Python lets you shoot yourself in the foot.
Of course -- [1,2,3] is not a tuple, so how would tuple know what to do
with it?
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-07-23 10:29 +1000 |
| Message-ID | <mailman.2447.1343003376.4697.python-list@python.org> |
| In reply to | #25832 |
On Mon, Jul 23, 2012 at 10:24 AM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: >> Methods are just functions, and you can call any method of any class >> with any object as its first parameter. > > Not quite: they have to be an instance of that class. > >> Though this mightn't work with everything. I wasn't able to paint a list >> as a tuple - "tuple.__repr__([1,2,3])" threw a TypeError. Oh well. >> There's a limit to the ways Python lets you shoot yourself in the foot. > > Of course -- [1,2,3] is not a tuple, so how would tuple know what to do > with it? Hmm. I would have thought that methods were like all other functions: they take their arguments and do code with them. Duck typing and all. I stand corrected, then. In any case, it works fine for methods of object, at least with Python 3 and with new-style classes in Py2. (Other than backward compatibility with old code, is there any reason to use an old-style class?) ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2012-07-23 01:40 +0000 |
| Message-ID | <500cab8a$0$29978$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #25833 |
On Mon, 23 Jul 2012 10:29:33 +1000, Chris Angelico wrote: > On Mon, Jul 23, 2012 at 10:24 AM, Steven D'Aprano > <steve+comp.lang.python@pearwood.info> wrote: >>> Methods are just functions, and you can call any method of any class >>> with any object as its first parameter. >> >> Not quite: they have to be an instance of that class. >> >>> Though this mightn't work with everything. I wasn't able to paint a >>> list as a tuple - "tuple.__repr__([1,2,3])" threw a TypeError. Oh >>> well. There's a limit to the ways Python lets you shoot yourself in >>> the foot. >> >> Of course -- [1,2,3] is not a tuple, so how would tuple know what to do >> with it? > > Hmm. I would have thought that methods were like all other functions: > they take their arguments and do code with them. Duck typing and all. I > stand corrected, then. > > In any case, it works fine for methods of object, at least with Python 3 > and with new-style classes in Py2. Naturally. In Python 3, and for new-style classes in 2, any instance is an instance of object. As the base class of everything, object has a generic repr that can handle everything. But subclasses are entitled to be more picky. What would you expect int.__repr__ do with a tuple for an argument? Raise an error, of course, and a TypeError at that. Which it does, in both 2 and 3: py> int.__repr__( (1, 2) ) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: descriptor '__repr__' requires a 'int' object but received a 'tuple' In general, you should assume that an arbitrary method will insist on its "self" argument actually being a valid instance of its class. There may be occasions where that is not the case, but don't count on it. I expect that this is under-specified behaviour: whether it works or not is implementation-specific, and so may change from compiler to compiler, or version to version. The mechanism behind method look-up is slightly complex, and changed significantly in Python 3. In Python 2, *both* these lookups: myclass.mymethod myinstance.mymethod return a *method object* -- the first case returns an "unbound method", which needs self to be provided when it is called, and the second returns a "bound method", which already knows what value of self to use (myinstance). In CPython, they are the same type with slightly different reprs, but that's an implementation detail. In either case, the method type enforces the rule that self is an instance of the type. In Python 3, the rule is slightly different. As before, *bound* methods (those that already have self supplied) are still returned when you look- up on an instance: myinstance.mymethod # returns a bound method object but unbound methods are no longer returned. (I presume you could still create one, by hand, but haven't tried.) Instead, looking up on the class returns the raw function object without the method wrapper, and that does no type-checking on self unless the developer put one in. Which built-in methods have got. > (Other than backward compatibility with old code, is there any reason to > use an old-style class?) Old-style classes have subtle differences in behaviour, and in principle at least are slightly faster. (At least they were back in Python 2.2.) Some differences include: 1) descriptor protocol does not work, including properties 2) super does not work 3) no __getattribute__ 4) magic dunder methods such as __add__ do not bypass the instance 5) automatic delegation is trivial So if you *require* such differences, then they would be good reasons for using classic classes. But frankly, as far as I can tell only #4 and #5 are positive differences, the others are reasons to avoid classic classes. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Devin Jeanpierre <jeanpierreda@gmail.com> |
|---|---|
| Date | 2012-07-22 20:44 -0400 |
| Message-ID | <mailman.2448.1343004339.4697.python-list@python.org> |
| In reply to | #25832 |
On Sun, Jul 22, 2012 at 8:29 PM, Chris Angelico <rosuav@gmail.com> wrote: > On Mon, Jul 23, 2012 at 10:24 AM, Steven D'Aprano > <steve+comp.lang.python@pearwood.info> wrote: >> Not quite: they have to be an instance of that class. ----8<---- > Hmm. I would have thought that methods were like all other functions: > they take their arguments and do code with them. Duck typing and all. > I stand corrected, then. On Python 3 you are correct. >>> class A: ... def print(self): ... print(self) ... >>> A.print(2) 2 -- Devin
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web