如何将文件结构表示为python对象

时间:2019-01-17 00:06:31

标签: python python-3.x object

我正在尝试找到一种将文件结构表示为python对象的方法,这样我就可以轻松获取特定路径,而不必键入所有字符串。这适用于我的情况,因为我具有静态文件结构(未更改)。

我以为我可以将目录表示为类,而目录中的文件则表示为类/静态变量。

我希望能够浏览python对象,以便它返回我想要的路径,即:

print(FileStructure.details.file1) # root\details\file1.txt
print(FileStructure.details) # root\details

我从下面的代码中得到的是:

print("{0}".format(FileStructure())) # root
print("{0}".format(FileStructure)) # <class '__main__.FileStructure'>
print("{0}".format(FileStructure.details)) # <class '__main__.FileStructure.details'>
print("{0}".format(FileStructure.details.file1)) # details\file1.txt

到目前为止,我的代码是...

import os 

class FileStructure(object): # Root directory
    root = "root"

    class details(object): # details directory
        root = "details"
        file1 = os.path.join(root, "file1.txt") # File in details directory
        file2 = os.path.join(root, "file2.txt") # File in details directory

        def __str__(self):
            return f"{self.root}"

    def __str__(self):
        return f"{self.root}"

我不想实例化类来完成这项工作。我的问题是:

  1. 如何调用类对象并使其返回字符串 文本
  2. 如何让嵌套类使用其父类?

2 个答案:

答案 0 :(得分:3)

让我们开始吧:您可能实际上并不想要这个。 Python3的pathlib API似乎比这更好,并且已经得到广泛支持。

root = pathlib.Path('root')
file1 = root / 'details' / 'file1'  # a Path object at that address

if file1.is_file():
    file1.unlink()
else:
    try:
        file1.rmdir()
    except OSError as e:
        # directory isn't empty

但是,如果由于某些原因而对此设置呆滞,则需要覆盖__getattr__以创建新的FileStructure对象并跟踪父母和孩子。

class FileStructure(object):
    def __init__(self, name, parent):
        self.__name = name
        self.__children = []
        self.__parent = parent

    @property
    def parent(self):
        return self.__parent

    @property
    def children(self):
        return self.__children

    @property
    def name(self):
        return self.__name

    def __getattr__(self, attr):
        # retrieve the existing child if it exists
        fs = next((fs for fs in self.__children if fs.name == attr), None)
        if fs is not None:
            return fs

        # otherwise create a new one, append it to children, and return it.
        new_name = attr
        new_parent = self
        fs = self.__class__(new_name, new_parent)
        self.__children.append(fs)
        return fs

然后将其用于:

root = FileStructure("root", None)
file1 = root.details.file1

您可以添加__str____repr__来帮助您的表示。您甚至可以包含一个path属性

# inside FileStructure
@property
def path(self):
    names = [self.name]
    cur = self
    while cur.parent is not None:
        cur = cur.parent
        names.append(cur.name)
    return '/' + '/'.join(names[::-1])

def __str__(self):
    return self.path

答案 1 :(得分:1)

预先:这是一个解决方案,但只需很少的更改即可满足您的要求。基本上,您需要实例来使type Foo = Readonly<{ foo: number bar: number }> type Bar = /* how to copy the Foo type, but make it writable? */ 正常工作,因此使用装饰器语法将类声明更改为声明的类的单例实例,这是作弊的。由于它是impossible to reference outer classes from nested classes implicitly,因此引用是显式执行的。为了重用__str__,将__str__file1做成了file2,因此他们可以使用@property实例的str形式来构建自己。

details

再次:尽管确实会产生您期望的行为,但这仍然是一个解决方案。我强烈怀疑您这里有an XY problem,但这可以回答所问的问题。