在 python 中的 os.walk 中分配实例

发布于 2024-12-21 12:03:18 字数 1905 浏览 1 评论 0原文

我正在尝试创建一个遍历目录的步行者。这是我部分工作的输入和输出。我正在使用测试目录,但我希望在任何导致一些问题的目录上完成此操作。

[IN]: print testdir  #name of the directory
[OUT]: ['j','k','l']  #directories under testdir

[IN]: print testdir.j
[OUT]: ['m','n']  # Files under testdir.j

这是到目前为止的代码:

class directory_lister:
    """Lists directories under root"""
    def __init__(self,path):
        self.path = path
        self.ex = []
        for item in os.listdir(path):
            self.ex.append(item)
    def __repr__(self):
        return repr(self.ex)

这将返回目录和文件,但我必须手动分配目录的名称。

testdir = directory_lister(path/to/testdir)
j = directory_lister(path/to/j)
etc

有没有一种方法可以自动化实例,例如:

for root,dirs,files in os.walk(/path/to/testdir/):
    for x in dirs:
        x = directory_lister(root) #I want j = directory_lister(path/to/j), k = directory_lister(path/to/k) and l = directory_lister(path/to/l) here.

是否可以:

class directory_lister:
    def __init__(self,path):
        self.path = path
        self.j = directory_lister(path + os.sep + j) # how to automate this attribute of the class when assigned to an instance??

上面的代码是错误的,因为对象 x 只成为一个实例,但必须手动定义 j、k、l。我是否必须使用另一个类或带有 getattr 的字典,但我总是遇到同样的问题。如果需要任何额外信息,请询问,我希望我说清楚了。

更新 2

有没有办法通过下面的 Anurag 将其他复杂功能添加到 DirLister 中?因此,当它到达一个文件 testdir/j/p 时,它会打印出文件 p 的第一行。

[IN] print testdir.j.p
[OUT] First Line of p

我创建了一个用于打印文件第一行的类:

class File:
    def __init__(self, path):
        """Read the first line in desired path"""
        self.path = path
        f = open(path, 'r')
        self.first_line = f.readline()
        f.close()

    def __repr__(self):
        """Display the first line"""
        return self.first_line

只需要知道如何将其合并到下面的类中。谢谢。

I am trying to create a walker that goes through directories. Here are the inputs and outputs which I have partly working. I am using a test directory but I would like this to be done on any directory which is leading to some problems.

[IN]: print testdir  #name of the directory
[OUT]: ['j','k','l']  #directories under testdir

[IN]: print testdir.j
[OUT]: ['m','n']  # Files under testdir.j

Here is the code so far:

class directory_lister:
    """Lists directories under root"""
    def __init__(self,path):
        self.path = path
        self.ex = []
        for item in os.listdir(path):
            self.ex.append(item)
    def __repr__(self):
        return repr(self.ex)

This returns the directories and files but I have to manually assign the names of the directories.

testdir = directory_lister(path/to/testdir)
j = directory_lister(path/to/j)
etc

Is there a way to automate instances such that:

for root,dirs,files in os.walk(/path/to/testdir/):
    for x in dirs:
        x = directory_lister(root) #I want j = directory_lister(path/to/j), k = directory_lister(path/to/k) and l = directory_lister(path/to/l) here.

Can there be a:

class directory_lister:
    def __init__(self,path):
        self.path = path
        self.j = directory_lister(path + os.sep + j) # how to automate this attribute of the class when assigned to an instance??

The code above is wrong as the object x only becomes an instance but j,k,l have to be defined manually. Do I have to use another class or a dictionary with getattr but I always run into the same problem. If any extra information is required please ask, I hope I made this clear.

UPDATE 2

Is there a way to add other complex functions to the DirLister by Anurag below? So when it gets to a file say testdir/j/p, it prints out the first line of file p.

[IN] print testdir.j.p
[OUT] First Line of p

I have made a class for printing out the first line of the file:

class File:
    def __init__(self, path):
        """Read the first line in desired path"""
        self.path = path
        f = open(path, 'r')
        self.first_line = f.readline()
        f.close()

    def __repr__(self):
        """Display the first line"""
        return self.first_line

Just need to know how to incorporate it in the class below. Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

执着的年纪 2024-12-28 12:03:18

我假设您希望子目录像属性一样可访问,您可以通过两种方式实现这一点:

  • 遍历文件列表并动态创建变量
  • 挂钩属性访问并根据需要正确返回列表器

我更喜欢第二种方法,因为它是惰性的,更好并且更容易实现

import os

class DirLister(object):
    def __init__(self, root):
        self.root = root
        self._list = None

    def __getattr__(self, name):
        try:
            var = super(DirLister).__getattr__(self, name)
            return var
        except AttributeError:
            return DirLister(os.path.join(self.root, name))

    def __str__(self):
        self._load()
        return str(self._list)

    def _load(self):
        """
        load once when needed
        """
        if self._list is not None:
            return
        self._list = os.listdir(self.root) # list root someway

root = DirLister("/")
print root.etc.apache2

输出:

['mods-enabled', 'sites-80', 'mods-available', 'ports.conf', 'envvars', 'httpd.conf', 'sites-available', 'conf.d', 'magic', 'apache2.conf', 'sites-enabled']

您可以改进它以进行更好的错误检查等

代码说明:这基本上是目录的递归列表,因此DirLister对象列出给定下的文件root 并且如果某个变量被访问点分符号它返回一个 DirLister 假设该属性是根目录下的文件夹。因此,如果我们尝试逐步创建 DirLister 类,它会更清晰

1- 一个简单的 DirLister ,仅列出其下的文件/文件夹

class DirLister(object):
    def __init__(self, root):
        self.root = root
        self._list = os.listdir(self.root)

2- 我们的简单列表器仅列出文件深一层,如果我们想获取子文件夹下的文件管理器,我们可以挂接到 __getattr__ 中,当使用 obj.varname 时,它会通过 varname 调用。因此,如果我们的 dir-lister 没有名为 varname 的属性,我们假设用户正在尝试访问给定根目录下的该目录,因此我们创建另一个根目录为 root+subdirname 的 DirLister

def __getattr__(self, name):
    try:
        var = super(DirLister).__getattr__(self, name)
        return var
    except AttributeError:
        return DirLister(os.path.join(self.root, name))

注意:首先我们检查该属性的基类,因为我们不想将所有变量访问视为子目录访问,如果没有这样的属性,则 AttributeError 然后我们为子文件夹创建一个新的 DirLister。

3-为了改进代码,以便我们不会列出所有文件夹,即使用户没有要求它们,我们仅在用户需要时列出,因此使用 load 方法,

def _load(self):
    if self._list is not None:
        return
    self._list = os.listdir(self.root) # list root someway

因此此方法会列出目录(如果尚未列出) ,并且应该在我们最终需要它时调用它,例如在打印列表时

编辑:正如OP所要求的,这里是递归列出整个树的替代方法,尽管我强烈建议不要

import os

class RecursiveDirLister(object):
    def __init__(self, root):
        self._sublist = []
        for folder in os.listdir(root):
            self._sublist.append(folder)
            path = os.path.join(root, folder)
            if not os.path.isdir(path):
                continue
            # add it as attribute, assuming that dir-name is valid python varname
            try:
                sublister = RecursiveDirLister(path)
            except OSError:
                continue#ignore permission errors etc
            setattr(self, folder, sublister)

    def __str__(self):
        return str(self._sublist)

etc = RecursiveDirLister("/etc")
print etc.fonts

输出:

['conf.avail', 'conf.d', 'fonts.conf', 'fonts.dtd']

I assume you want sub-dir to be accessible like a attribute, you can achieve that two ways

  • Go thru list of files and create variables dynamically
  • Hook into attribute access and correctly return listers as needed

I prefer second approach as it is lazy, better and easier to implement

import os

class DirLister(object):
    def __init__(self, root):
        self.root = root
        self._list = None

    def __getattr__(self, name):
        try:
            var = super(DirLister).__getattr__(self, name)
            return var
        except AttributeError:
            return DirLister(os.path.join(self.root, name))

    def __str__(self):
        self._load()
        return str(self._list)

    def _load(self):
        """
        load once when needed
        """
        if self._list is not None:
            return
        self._list = os.listdir(self.root) # list root someway

root = DirLister("/")
print root.etc.apache2

output:

['mods-enabled', 'sites-80', 'mods-available', 'ports.conf', 'envvars', 'httpd.conf', 'sites-available', 'conf.d', 'magic', 'apache2.conf', 'sites-enabled']

You can improve this to have better error checking etc

Code explanation: this is basically a recursive listing of directory, so a DirLister objects lists files under the given root and if some variable is accessed with dotted notation it returns a DirLister assuming that that attribute is a folder under the root. So if we try to create DirLister class step by step it will be more clear

1- A simple DirLister which just lists files/folders under it

class DirLister(object):
    def __init__(self, root):
        self.root = root
        self._list = os.listdir(self.root)

2- Our simple lister just list files one level deep, if we want to get filers under subfolders we can hook into __getattr__ which is called with varname when obj.varname is used. So if our dir-lister doesn't have a attribute named varname we assume user is trying to access that directory under given root, so we create another DirLister whose root is root+subdirname

def __getattr__(self, name):
    try:
        var = super(DirLister).__getattr__(self, name)
        return var
    except AttributeError:
        return DirLister(os.path.join(self.root, name))

Note: first we check base class for that attribute because we don't want to treat all variable access as sub-dir access, if there is no such attribute hence AttributeError then we create a new DirLister for sub-folder.

3- To improve code so that we don't list all folders even if user did not ask for them, we only list when user requires, hence a load method

def _load(self):
    if self._list is not None:
        return
    self._list = os.listdir(self.root) # list root someway

so this method lists dir if not already listed, and this should be called when we finally need it e.g. while printing the list

Edit: as asked by OP here is the alternate method of recursively list whole tree though I would strongly recommend against it

import os

class RecursiveDirLister(object):
    def __init__(self, root):
        self._sublist = []
        for folder in os.listdir(root):
            self._sublist.append(folder)
            path = os.path.join(root, folder)
            if not os.path.isdir(path):
                continue
            # add it as attribute, assuming that dir-name is valid python varname
            try:
                sublister = RecursiveDirLister(path)
            except OSError:
                continue#ignore permission errors etc
            setattr(self, folder, sublister)

    def __str__(self):
        return str(self._sublist)

etc = RecursiveDirLister("/etc")
print etc.fonts

output:

['conf.avail', 'conf.d', 'fonts.conf', 'fonts.dtd']
满天都是小星星 2024-12-28 12:03:18

不确定你在问什么,但这行得通吗?

for root,dirs,files in os.walk(/path/to/testdir/):
    listers = dict((dir, directory_lister(dir)) for dir in dirs)
    #now you can use:
    listers['j']
    listers['k']
    listers['l']

Not sure what you're asking, but would this work?

for root,dirs,files in os.walk(/path/to/testdir/):
    listers = dict((dir, directory_lister(dir)) for dir in dirs)
    #now you can use:
    listers['j']
    listers['k']
    listers['l']
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文