[Python-ideas] Are we supposed to be able to have our own class dictionary in python 3?

Daniel Moisset dfmoisset at gmail.com
Sun Nov 4 06:43:39 EST 2018


I think the documentation is correct but you misinterpreted the intent of
that code. The code you're quoting, which is an example, is not about
ending up with a custom dict within the instance, the intent of the author
was just to captur the memeber_names list. So what it does for that is
customizing the class dict in prepare(), but then in __init__ it
*intentionally* converts it to a regular dict after extracting the
member_names. The goal of the example is ending up with instances with
regular attribute dicts but an extra member_names attributes, while I think
that you're looking for to end up with a custom attribute dict (so in
*your* case, you do not need to do the copying)

On Sun, 4 Nov 2018 at 00:03, Amit Green <amit.mixie at gmail.com> wrote:

> Thanks Daniel,
>
> I found my answer here (using your link):
> https://docs.python.org/3/reference/datamodel.html#preparing-the-class-namespace
>
> """
> When a new class is created by type.__new__, the object provided as the
> namespace parameter is copied to a new ordered mapping and the original
> object is discarded.
> """
>
> Therefore the answer seems to be that
> https://www.python.org/dev/peps/pep-3115/ needs to be updated & fixed.
>
> Replace the following:
>
> """
>
>     def __new__(cls, name, bases, classdict):
>         # Note that we replace the classdict with a regular
>         # dict before passing it to the superclass, so that we
>         # don't continue to record member names after the class
>         # has been created.
>         result = type.__new__(cls, name, bases, dict(classdict))
>         result.member_names = classdict.member_names
>         return result
>
> """
>
> With:
>
> """
> def __new__(cls, name, bases, classdict):
>
>         result = type.__new__(cls, name, bases, classdict)
>         result.member_names = classdict.member_names
>         return result
>
> """
>
> Removing the incorrect comments & the copying of `classdict`
>
> I will go file a bug report to that effect.
>
> Thanks,
>
> Joy Diamond.
>
>
>
> On Sat, Nov 3, 2018 at 7:55 PM Daniel Moisset <dfmoisset at gmail.com> wrote:
>
>> If I understood correctly what you want, it's possible with a metaclass.
>> Check the __prepare__ method at
>> https://docs.python.org/3/reference/datamodel.html#preparing-the-class-namespace
>> and Pep 3115
>>
>> On Sat, 3 Nov 2018, 20:55 Joy Diamond <python.gem at gmail.com wrote:
>>
>>> Team,
>>>
>>> Are we supposed to be able to have our own class dictionary in python 3?
>>>
>>> If we currently cannot -- do we want to be able to?
>>>
>>> That we can have out own class dictionary in python 3 is strongly
>>> implied in the following at https://www.python.org/dev/peps/pep-3115/
>>> where it says:
>>>
>>> """
>>>
>>>     # The metaclass invocation
>>>     def __new__(cls, name, bases, classdict):
>>>         # Note that we replace the classdict with a regular
>>>         # dict before passing it to the superclass, so that we
>>>         # don't continue to record member names after the class
>>>         # has been created.
>>>         result = type.__new__(cls, name, bases, dict(classdict))
>>>         result.member_names = classdict.member_names
>>>         return result
>>>
>>> """
>>>
>>> I don't understand this.  As far as I can tell, no matter what class
>>> dictionary you pass into `type.__new__` it creates a copy of it.
>>>
>>> Am I missing something?  Is this supposed to work?  Is the documentation
>>> wrong?
>>>
>>> Thanks,
>>>
>>> Joy Diamond.
>>>
>>> Program that shows that the class dictionary created is not what we pass
>>> in --- Shows the actual symbol table is `dict` not `SymbolTable`
>>>
>>> class SymbolTable(dict):
>>>     pass
>>>
>>> members = SymbolTable(a = 1)
>>>
>>> X = type('X', ((object,)), members)
>>>
>>> members['b'] = 2
>>>
>>> print('X.a: {}'.format(X.a))
>>>
>>> try:
>>>     print('X.b: {}'.format(X.b))
>>> except AttributeError as e:
>>>     print('X.b: does not exist')
>>>
>>> #
>>> #   Get the actual symbol table of `X`, bypassing the mapping proxy.
>>> #
>>> X__symbol_table = __import__('gc').get_referents(X.__dict__)[0]
>>>
>>> print('The type of the actual symbol table of X is: {} with keys:
>>> {}'.format(
>>>       type(X__symbol_table),
>>>       X__symbol_table.keys()))
>>>
>>>
>>> # Prints out
>>> # X.a: 1
>>> # X.b: does not exist
>>> # The type of the actual symbol table of X is: <class 'dict'> with keys:
>>> dict_keys(['a', '__module__', '__dict__', '__weakref__', '__doc__'])
>>>
>>>
>>> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=icon> Virus-free.
>>> www.avast.com
>>> <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=link>
>>> <#m_7342312465347859571_m_3863327966708087084_m_7370047320667964513_m_603818574152564677_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
>>> _______________________________________________
>>> Python-ideas mailing list
>>> Python-ideas at python.org
>>> https://mail.python.org/mailman/listinfo/python-ideas
>>> Code of Conduct: http://python.org/psf/codeofconduct/
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20181104/68bd6b35/attachment-0001.html>


More information about the Python-ideas mailing list