1

It's possible to use type in Python to create a new class object, as you probably know:

A = type('A', (object,), {})

a = A() # create an instance of A

What I'm curious about is whether there's any problem with creating different class objects with the same name, eg, following on from the above:

B = type('A', (object,), {})

In other words, is there an issue with this second class object, B, having the same name as our first class object, A?


The motivation for this is that I'd like to get a clean copy of a class to apply different decorators to without using the inheritance approach described in this question.

So I'd like to define a class normally, eg:

class Fruit(object):
    pass

and then make a fresh copy of it to play with:

def copy_class(cls):
    return type(cls.__name__, cls.__bases__, dict(cls.__dict__))

FreshFruit = copy_class(fruit)

In my testing, things I do with FreshFruit are properly decoupled from things I do to Fruit.

However, I'm unsure whether I should also be mangling the name in copy_class in order to avoid unexpected problems.

In particular, one concern I have is that this could cause the class to be replaced in the module's dictionary, such that future imports (eg, from module import Fruit return the copied class).

Community
  • 1
  • 1
sapi
  • 9,944
  • 8
  • 41
  • 71

1 Answers1

2

There is no reason why you can't have 2 classes with the same __name__ in the same module if you want to and have a good reason to do so.

e.g. In your example from module import Fruit -- python doesn't care at all about the __name__ of the class. It looks in the module's globals for Fruit and imports what it finds there.


Note that, in general, this approach isn't great if you're using super (although the same can be said for class decorators ...):

class A(Base):
    def foo(self):
        super(A, self).foo()

B = copy_class(A)

In this case, when B.foo is called, it will end up calling super(A, self) which could lead to funky behaviour in a number of circumstances. . .

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • I guess that really is what my question boils down to, thanks. So Python won't use `__name__` for anything internally? – sapi Sep 30 '14 at 05:34
  • @sapi -- Nothing "important". Some objects might use it for `repr` or do some sort of introspection, etc. But at the end of the day, `__name__` is a writeable attribute on a class so it can't be depended on to be the same as the "name" in whatever namespace the class lives. – mgilson Sep 30 '14 at 05:37