There is a way to do it, but it's more involved than you might think.
Where does the name __name__ come from? The answer is that it's a global variable. This is to be expected, since the global namespace is the module namespace. For example:
>>> globals()['__name__']
'__main__'
If you look up callables in the Standard Type Hierarchy of python's Data Model documentation, you will find that a function's __globals__ attribute is read-only. That means that the function A.name will always look up its global attributes in the namespace of module a (not that the module namespace itself is read-only).
The only way to alter globals for a function is to copy the function object. This has been hashed out on Stack Overflow at least a couple of times:
Copying classes has come up as well:
Solution 1
I've gone ahead and implemented both techniques in a utility library I made called haggis. Specifically, haggis.objects.copy_class will do what you want:
from haggis.objects import copy_class
import a
class B(copy_class(A, globals(), __name__)):
pass
This will copy A. All function code and non-function attributes will be referenced directly. However, function objects will have the updated __globals__ and __module__ attributes applied.
The major problem with this method is that it breaks your intended inheritance hierarchy slightly. Functionally, you won't see a difference, but issubclass(b.B, a.A) will no longer be true.
Solution 2 (probably the best one)
I can see how it would be a bit cumbersome to copy all the methods of A and break the inheritance hierarchy by doing this. Luckily, there is another method, haggis.objects.copy_func, which can help you copy just the name method out of A:
from haggis.objects import copy_func
import a
class B(A):
name = copy_func(A.name, globals(), __name__)
This solution is a bit more robust, because copying classes is much more finicky than copying functions in python. It's fairly efficient because both versions of name will actually share the same code object: only the metadata, including __globals__, will be different.
Solution 3
You have a much simpler solution available if you can alter A ever so slightly. Every (normal) class in python has a __module__ attribute that is the __name__ attribute of the module where it was defined.
You can just rewrite A as
class A:
def name(self):
# Do something
print("Did in %s" % self.__module__)
Using self.__module__ instead of __name__ is roughly analogous to using type(self) instead of __class__.
Solution 4
Another simple idea is to properly override A.name:
class B(A):
def name(self):
# Do something
LOG.debug("Did something")
Of course I can see how this would not work well if # Do something is a complex task that is not implemented elsewhere. It's probably much more efficient to just copy the function object directly out of A.