<p>On Feb 26, 2012 10:27 AM, "Simon Sapin" <<a href="mailto:simon.sapin@kozea.fr" target="_blank">simon.sapin@kozea.fr</a>> wrote:</p><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



Le 24/02/2012 00:34, Victor Stinner a écrit :<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I'm trying to create read-only objects using a "frozendict" class.<br>
frozendict is a read-only dict. I would like to use frozendict for the<br>
class dict using a metaclass, but type.__new__() expects a dict and<br>
creates a copy of the input dict.<br>
<br>
I would be nice to support custom dict type: OrderedDict and<br>
frozendict for example. It looks possible to patch CPython to<br>
implement this feature, but first I would like first to know your<br>
opinion about this idea:-)<br>
</blockquote>
<br>
Hi,<br>
<br>
Combining ideas from other messages in this thread: would this work?<br>
<br>
1. Inherit from frozendict<br>
2. Define a __getattr__ that defers to frozendict.__getitem__<br>
3. Use an empty __slots__ so that there is no "normal" instance attribute.<br>
<br>
Thinking about it a bit more, it’s probably the same as having a normal __dict__ and raising in __setattr__ and __delattr__. Isn’t this how you implement frozendict? (Raise in __setitem__, __delitem__, update, etc.)<br>
<br>
Regards,<br>
-- <br>
Simon Sapin<br>
______________________________<u></u>_________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
<a href="http://mail.python.org/mailman/listinfo/python-ideas" target="_blank">http://mail.python.org/<u></u>mailman/listinfo/python-ideas</a></blockquote><div><br></div><div>Using frozendict, and especially inheriting from it sounds unnecessarily complicated to me.  A simple class which doesn't allow changes to instance attributes could be implemented something like this:</div>

<div><br></div><div><div>class Three_inst:</div><div>    </div><div>    @property</div><div>    def value(self):</div><div>        return 3</div><div><br></div><div>    def __setattr__(self, attr, value):</div><div>        raise AttributeError</div>

<div><br></div><div>    def __delattr__(self, attr):</div><div>        raise AttributeError</div></div><div><br></div><div>Or, if you're worried about changes to the class attributes, you could do basically the same thing using a metaclass (python 2.7 syntax):</div>

<div><br></div><div><div>class FinalMeta(type):</div><div><br></div><div>    def __setattr__(cls, attr, value):</div><div>        if attr in cls.__dict__ or '__done__' in cls.__dict__:</div><div>            raise AttributeError</div>

<div>        else:</div><div>            type.__setattr__(cls, attr, value)</div><div><br></div><div>    def __delattr__(cls, attr):</div><div>        raise AttributeError</div><div><br></div><div><br></div><div>class Three:</div>

<div>    __metaclass__ = FinalMeta</div><div>    value = 3</div></div><div>    __done__ = True   # There may be a neater way to do this...</div><div><br></div><div>Each of the following examples will fail:</div><div><br>
</div>
<div>>>> Three.another_value = 4</div><div>>>> Three.value = 4</div><div>>>> del Three.value</div><div>>>> three = Three(); three.value = 4</div><div><br></div><div>Actually, I think this is quite a nice illustration of what can be done with metaclasses!</div>

<div><br></div><div>David</div></div>