about types.new_class and module
Peter Otten
__peter__ at web.de
Mon Mar 4 14:55:12 EST 2019
MRAB wrote:
> On 2019-03-04 18:02, Jimmy Girardet wrote:
>> Hello,
>>
>> I'm looking for an explanation where live classes created by
>> types.new_class() :
>>
>> py> import types
>>
>> py> types.new_class('A')
>>
>> types.A
>>
>> py> types.A
>>
>> AttributeError: module 'types' has no attribute 'A'
>>
>> py> _.__module__
>>
>> 'types'
>>
>>
>> The new class comes from `types` module without being inside.
>>
>> That's annoying to me for my use case :
>>
>> I'm trying to create dataclasses on the fly using make_dataclass (which
>> uses types.new_class). For new created classes, I have a cache to not
>> recreate twice the same class.
>>
>> But I want to be sure not to override an existing class somewhere in the
>> namespace which is already 'types.MyNewclass'. but how to check it if
>> it's not in types ?
>>
>> To be clear :
>>
>> make_dataclass('Bla', {}) should raise an error if something named
>> 'types.Bla' already exists.
>>
>> I hope I'm clear enough.
>>
> 'new_class' creates a new class with the given name and returns a
> reference to it.
>
> The class doesn't 'live' anywhere.
>
> Although you might /think/ that an object lives in a certain namespace,
> it's just that there's a name there that's bound to the object.
>
> You can, in fact, create 2 classes with the same name.
>
> >>> import types
> >>> t1 = types.new_class('A')
> >>> t2 = types.new_class('A')
> >>> t1 is t2
> False
However, the underlying type() call assumes that you are going to inject the
class into the current module -- which is why the OP's class appears to be
part of the types module
>>> types.new_class("Foo")
<class 'types.Foo'>
and
>>> type("Foo", (), {})
<class '__main__.Foo'>
appears to be in __main__. This is correct in the majority of cases where
the class is defined with
class A:
pass
which can be thought of as syntactic sugar for
A = type("A", (), {})
In the case of types.new_class() it is rather confusing -- perhaps the
function should follow the example of collections.namedtuple and set the
__module__ attribute to the caller's namespace.
More information about the Python-list
mailing list