Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #66206
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Subject | Re: Using a subclass for __dict__ |
| Date | 2014-02-13 20:10 +0100 |
| Organization | None |
| References | <CAE+T62bYFSdYmYRbY1Cuz51zym-NMYv0O5CnJvsbTR41oUZsag@mail.gmail.com> |
| Newsgroups | comp.lang.python |
| Message-ID | <mailman.6855.1392318635.18130.python-list@python.org> (permalink) |
Demian Brecht wrote: > Using bases in a metaclass, I've been able to easily figure out when > an attribute is being added to an instance of a class. However, what > I'm /actually/ looking to do is to intercept when attributes are being > added to a class (not an instance of). I thought that I'd be able to > do so by passing in a subclass of dict to type.__new__ of the > metaclass's __new__ and implementing a custom __setitem__, but > apparently that's not the case. > > If you're curious as to why I'm doing this, I'm trying to clean up > https://gist.github.com/demianbrecht/6944269 and get rid of the > late_bind method there in favour of using the appropriate magic > methods. The intention is to piggyback off of abc's > __abstractmethods__ in order to implement a "looks_like" method that > checks that one class conforms to an unrelated class's interface > rather than using inheritance to enforce interface implementations at > class creation time. This is /only/ intended to be a proof of concept > for demonstration purposes and nothing that I'd ever actually > implement, so no need for flaming the concept :) > > # test.py > > class Dict(dict): > def __setattr__(self, key, value): > print 'Dict.__setattr__' > dict.__setattr__(self, key, value) > > def __setitem__(self, key, value): > print 'Dict.__setitem__' > dict.__setitem__(self, key, value) > > class Bar(object): > def __setattr__(self, key, value): > print 'Bar.__setattr__' > object.__setattr__(self, key, value) > > class metafoo(type): > def __new__(mcls, name, bases, dct): > return type.__new__(mcls, name, (Bar,), Dict(dct)) > > class Foo(object): > __metaclass__ = metafoo > >>>> import test >>>> f = test.Foo() >>>> f.foo = 'bar' > Bar.__setattr__ # expected >>>> test.Foo.foo = 'bar' > # I'm expecting Dict.__setattr__ here, but... *crickets* > > Am I missing something here, or do I just have to live with what I > currently have in my gist? I don't really understand what you are trying to do in the gist, perhaps you want <http://docs.python.org/dev/reference/datamodel.html#customizing-instance-and-subclass-checks> ? Anyway, intercepting __setattr__() in the class becomes easy once you remember that a class is just an instance of its metaclass: >>> class FooMeta(type): ... def __setattr__(self, name, value): ... print value, "-->", name ... super(FooMeta, self).__setattr__(name, value) ... >>> class Foo: ... __metaclass__ = FooMeta ... >>> Foo.bar = "baz" baz --> bar Python 3 has a bit more to offer in this area, see <http://docs.python.org/dev/reference/datamodel.html#preparing-the-class-namespace>
Back to comp.lang.python | Previous | Next | Find similar | Unroll thread
Re: Using a subclass for __dict__ Peter Otten <__peter__@web.de> - 2014-02-13 20:10 +0100
csiph-web