[Python-Dev] type(obj) vs. obj.__class__

Peter Ludemann pludemann at google.com
Sun Oct 18 20:09:03 EDT 2015


I re-coded the "too clever by half" RingBuffer to use the same design but
with delegation ... and it ran 50% slower. (Code available on request)
Then I changed it to switch implementations of append() and get() when it
got full (the code is below) and it ran at essentially the same speed as
the original. So, there's no need to be so clever with __class__. Of
course, this trick of replacing a method is also "too clever by half"; but
an instance variable for "full" slows it down by 15%.

class RingBuffer(object):
    def __init__(self, size_max):
        self.max = size_max
        self.data = []
        self.cur = 0
    def append(self, x):
        self.data.append(x)
        if len(self.data) == self.max:
            self.append = self.append_full
    def append_full(self, x):
        self.data[self.cur] = x
        self.cur = (self.cur + 1) % self.max
    def get(self):
        return self.data[self.cur:] + self.data[:self.cur]



On 18 October 2015 at 08:45, David Mertz <mertz at gnosis.cx> wrote:

> This recipe looks like a bad design to me to start with.  It's
> too-clever-by-half, IMO.
>
> If I were to implement RingBuffer, I wouldn't futz around with the
> __class__ attribute to change it into another thing when it was full.  A
> much more obvious API for users would be simply to implement a
> RingBuffer.isfull() method, perhaps supported by an underlying
> RingBuffer._full boolean attribute.  That's much friendlier than expecting
> people to introspect the type of the thing for a question that only
> occasionally matters; and when it does matter, the question is always
> conceived exactly as "Is it full?" not "What class is this currently?"
>
> So I think I'm still waiting for a compelling example where type(x) !=
> x.__class__ would be worthwhile (yes, of course it's *possible*)
>
> On Sat, Oct 17, 2015 at 10:55 PM, Steven D'Aprano <steve at pearwood.info>
> wrote:
>
>> On Sat, Oct 17, 2015 at 03:45:19PM -0600, Eric Snow wrote:
>> > In a recent tracker issue about OrderedDict [1] we've had some
>> > discussion about the use of type(od) as a replacement for
>> > od.__class__.
>> [...]
>> > The more general question of when we use type(obj) vs. obj.__class__
>> > applies to both the language and to all the stdlib as I expect
>> > consistency there would result in fewer surprises.  I realize that
>> > there are some places where using obj.__class__ makes more sense (e.g.
>> > for some proxy support).  There are other places where using type(obj)
>> > is the way to go (e.g. special method lookup).  However, the
>> > difference is muddled enough that usage is inconsistent in the stdlib.
>> > For example, C-implemented types use Py_TYPE() almost exclusively.
>> >
>> > So, would it make sense to establish some concrete guidelines about
>> > when to use type(obj) vs. obj.__class__?  If so, what would those be?
>> > It may also be helpful to enumerate use cases for "type(obj) is not
>> > obj.__class__".
>>
>> I for one would like to see a definitive explanation for when they are
>> different, and when you should use one or the other. The only
>> obvious example I've seen is the RingBuffer from the Python Cookbook:
>>
>> http://code.activestate.com/recipes/68429-ring-buffer/
>>
>>
>>
>> --
>> Steve
>> _______________________________________________
>> Python-Dev mailing list
>> Python-Dev at python.org
>> https://mail.python.org/mailman/listinfo/python-dev
>> Unsubscribe:
>> https://mail.python.org/mailman/options/python-dev/mertz%40gnosis.cx
>>
>
>
>
> --
> Keeping medicines from the bloodstreams of the sick; food
> from the bellies of the hungry; books from the hands of the
> uneducated; technology from the underdeveloped; and putting
> advocates of freedom in prisons.  Intellectual property is
> to the 21st century what the slave trade was to the 16th.
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/pludemann%40google.com
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20151018/9b785de4/attachment.html>


More information about the Python-Dev mailing list