Confused about __prepare__

Discussion in 'Python' started by andrew cooke, Apr 7, 2011.

  1. andrew cooke

    andrew cooke Guest

    In the code below I use __prepare__ to change the class dictionary so that a tuple is stored in __setitem__(). Since __getitem__() removes the tuple I wasn't expecting any problems, but it seems that __init__ is being retrieved via some other mechanism. Why? Is a copy of the dict being made somewhere? If so, can I change that?

    Thanks,
    Andrew


    class TupleDict(dict):
    '''Stores additional info, but removes it on __getitem__().'''

    def __setitem__(self, key, value):
    print('setting', key, value)
    super(TupleDict, self).__setitem__(key, (value, 'secret'))

    def __getitem__(self, key):
    value = super(TupleDict, self).__getitem__(key)
    print('getting', key, value[0]) # drop secret
    return value[0]


    class TupleMeta(type):

    @classmethod
    def __prepare__(metacls, name, bases, **kargs):
    print('in prepare')
    return TupleDict()

    def __new__(cls, name, bases, classdict):
    print('in new')
    return type.__new__(cls, name, bases, classdict)


    class C(metaclass=TupleMeta):

    def __init__(self):
    self.a = 1


    c = C()

    in prepare
    setting __module__ __main__
    setting __init__ <function __init__ at 0x7f37cbad40d8>
    in new
    Traceback (most recent call last):
    File ..., line 34, in <module>
    c = C() # TypeError: 'tuple' object is not callable
    TypeError: 'tuple' object is not callable
     
    andrew cooke, Apr 7, 2011
    #1
    1. Advertising

  2. andrew cooke

    Chris Rebert Guest

    On Thu, Apr 7, 2011 at 3:31 PM, andrew cooke <> wrote:
    >
    > In the code below I use __prepare__ to change the class dictionary so that a tuple is stored in __setitem__().  Since __getitem__() removes thetuple I wasn't expecting any problems, but it seems that __init__ is beingretrieved via some other mechanism.  Why?


    I suspect you're being bitten by
    http://docs.python.org/dev/reference/datamodel.html#special-method-lookup

    In particular: "implicit special method lookup generally also bypasses
    the __getattribute__() method".

    __init__() is a special method.
    The default __getattribute__() implementation consults an object's __dict__..
    type.__new__() presumably does an implicit special method lookup for
    __init__() behind the scenes.

    Hence, your custom __dict__ is bypassed.

    Cheers,
    Chris
    --
    http://blog.rebertia.com
     
    Chris Rebert, Apr 8, 2011
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. DJ Miller

    Confused and bewildered.

    DJ Miller, Jul 31, 2003, in forum: ASP .Net
    Replies:
    4
    Views:
    1,083
    DJ Miller
    Sep 4, 2003
  2. RichGK
    Replies:
    1
    Views:
    397
    SStory
    Jul 31, 2004
  3. Cobra Pilot

    Confused. Need Help!

    Cobra Pilot, Jul 22, 2003, in forum: Perl
    Replies:
    1
    Views:
    968
    Shawn Corey
    Jul 22, 2003
  4. Steven D'Aprano
    Replies:
    0
    Views:
    296
    Steven D'Aprano
    Jan 9, 2012
  5. Chris Angelico
    Replies:
    0
    Views:
    54
    Chris Angelico
    May 18, 2014
Loading...

Share This Page