Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!news.mixmin.net!feeds.phibee-telecom.net!newsfeed.xs4all.nl!newsfeed6.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.002 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'attribute': 0.05; 'assign': 0.07; 'classes.': 0.07; 'subject:help': 0.07; 'python': 0.09; 'assigning': 0.09; 'derived': 0.09; 'dict': 0.09; 'aug': 0.13; 'a(object):': 0.16; 'above?': 0.16; 'b()': 0.16; 'bug,': 0.16; 'code).': 0.16; 'declaration,': 0.16; 'massimo': 0.16; 'merely': 0.16; 'mon,': 0.16; 'wrote:': 0.17; 'documented': 0.17; 'instance,': 0.17; 'changes': 0.20; 'event,': 0.22; 'this:': 0.23; "i've": 0.23; 'pass': 0.25; 'header:In-Reply-To:1': 0.25; 'updating': 0.27; '(as': 0.27; 'object,': 0.27; 'message- id:@mail.gmail.com': 0.27; '(perhaps': 0.29; 'accomplished': 0.29; 'cases.': 0.29; 'probably': 0.29; 'class': 0.29; 'this.': 0.29; 'usually': 0.30; 'normally': 0.30; 'expect': 0.31; 'true.': 0.33; 'to:addr:python-list': 0.33; 'received:google.com': 0.34; 'pm,': 0.35; 'received:209.85': 0.35; 'but': 0.36; 'should': 0.36; 'problems': 0.36; 'correctly': 0.37; 'does': 0.37; 'why': 0.37; 'received:209': 0.37; 'far': 0.37; 'subject:: ': 0.38; 'object': 0.38; 'some': 0.38; 'instead': 0.39; 'to:addr:python.org': 0.39; 'skip:" 10': 0.40; 'header:Received:5': 0.40; 'think': 0.40; 'your': 0.60; 'behavior': 0.64; 'here': 0.65; '20,': 0.65; 'discovered': 0.83; 'anywhere.': 0.84; 'dict,': 0.84; 'to:name:python': 0.84 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type; bh=n6Z2wKfh/89C7juyszFftHypWP6xiEJ0NrbYdh3/8WY=; b=R8eYAKiHHyBDjoAvdY2yD8hJUW1rPfgD4ndLameugfW73iFjGAxdMJtsUSUd/IB5UH +nN1CKpe3cUmLT3wXimUXte4ShwuIsN5rxjV7O8ZcazxVtyrD4wmsXPBvOt4IIrxH91X 1Sl8Rcm9vz0U8AS+2EMMVlR//4QpAR3CUK8hV1a6MN+rw1EW2gWvsM0trc5HzQedoonT xn3vOIRb0KI5bDioH+dSBa8qecetuKMM0/NGTTdw9ECmsmy1KAtRVkovneIxnoHpyYNu RaaCILw7PscoeDuik6owCKTDruxVVZCzixOzoinI2YNhhejBI0DX51ogm5FZjxJ82ju2 6U8g== MIME-Version: 1.0 In-Reply-To: <21067364-7b9c-4415-bad1-947961497343@u20g2000yqc.googlegroups.com> References: <21067364-7b9c-4415-bad1-947961497343@u20g2000yqc.googlegroups.com> From: Ian Kelly Date: Mon, 20 Aug 2012 12:39:38 -0600 Subject: Re: Class.__class__ magic trick help To: Python Content-Type: text/plain; charset=ISO-8859-1 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 38 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1345488010 news.xs4all.nl 6842 [2001:888:2000:d::a6]:36639 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:27523 On Mon, Aug 20, 2012 at 12:01 PM, Massimo Di Pierro wrote: > I discovered I can do this: > > class A(object): pass > class B(object): > __class__ = A # <<<< magic > > b = B() > isinstance(b,A) # returns True (as if B derived from A) > isinstance(b,B) # also returns True > > I have some reasons I may want to do this (I an object with same > methods as a dict but it is not derived from dict and I want > isinstance(x,dict)==True to use it in place of dict in some other > code). > > What are the problems with the magic trick above? Why does it work? Normally with __class__ assignment, you would assign to the __class__ attribute of the *instance*, not the class declaration. This actually changes the class of the object, and so isinstance(b, B) would no longer return True. I've never heard of assigning it in the class declaration, and as far as I know, this behavior isn't documented anywhere. I expect that what's happening here is that Python is not actually updating the class of the instance, but that A is merely assigned to the "__class__" attribute in the class dict, and that isinstance is somehow (perhaps accidentally) finding this. So I think this is probably a bug, and I would not rely on it to work correctly in all cases. In any event, the use case that you're looking for is usually accomplished using abstract base classes. Instead of "isinstance(x, dict)", you should use "isinstance(x, collections.MutableMapping)", and then inherit your class from or register it with the MutableMapping ABC.