18

Suppose you have the following:

$ more a.py
import os

class A(object):
    def getfile(self):
        return os.path.abspath(__file__)

-

$ more b.py
import a

class B(a.A):
    pass

-

>>> import b
>>> x=b.B()
>>> x.getfile()
'/Users/sbo/tmp/file/a.py'

This is clear. No surprise from this code. Suppose however that I want x.getfile() to return the path of b.py without having to define another copy of getfile() under class B.

I did this

import os
import inspect

class A(object):
    def getfile(self):
        return os.path.abspath(inspect.getfile(self.__class__))

I was wondering if there's another strategy (and in any case, I want to write it here so it can be useful for others) or potential issues with the solution I present.

CW as it's more a discussion question, or a yes/no kind of question

1
  • The solution shown in the question seems better to me than those of the answers. Less access of dunder attributes and no overriding of __init__ in the child class needed. Commented Mar 21, 2024 at 17:53

2 Answers 2

18
sys.modules[self.__class__.__module__].__file__
Sign up to request clarification or add additional context in comments.

4 Comments

I like this, but one thing to note is that you will be given the byte compiled module.
I don't. I think it's awful. It's a bad method, and anyone that uses it is a bad person.
This is very old but: Is there a way to do this from a static method / without instantiating?
@IgnacioVazquez-Abrams Care to elaborate on what makes this method so awful?
8

Was able to get this working in python 3 as follows:

import os

class Parent:

    def __init__(self, filename=__file__):
        self.filename = filename

    def current_path(self):
        pth, _ = os.path.split(os.path.abspath(self.filename))
        return pth

Then in a different module...

from practice.inheritance.parent import Parent

class Child(Parent):

    def __init__(self):
        super().__init__(__file__)

...accessing current_path() from either Parent or Child returns the respective module path as expected.

>>> from practice.inheritance.parent import Parent
>>> parent = Parent()
>>> print(parent.current_path())
/Users/davidevans/PycharmProjects/play35/practice/inheritance

>>> from practice.inheritance.subpackage.child import Child
>>> child = Child()
>>> print(child.current_path())
/Users/davidevans/PycharmProjects/play35/practice/inheritance/subpackage

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.