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

以下のクラスに組み込む方法を知る必要があります。ありがとうございました。

4

2 に答える 2

1

サブディレクトリに属性のようにアクセスできるようにしたいと思います.2つの方法でそれを実現できます

  • ファイルのリストを調べて変数を動的に作成する
  • 属性アクセスにフックし、必要に応じてリスターを正しく返す

怠惰で、実装がより良く、簡単であるため、2番目のアプローチを好みます

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オブジェクトは指定されたルートの下のファイルをリストし、ドット表記で変数にアクセスすると、その属性がルートの下のフォルダーであると仮定して DirLister を返します。したがって、DirListerクラスを段階的に作成しようとすると、より明確になります

1-そのDirLister下にファイル/フォルダーをリストするだけの単純なもの

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

2- この単純なリスターは、1 レベルの深さでファイルを一覧表示するだけ__getattr__ですobj.varname。したがって、dir-lister に varname という名前の属性がない場合、ユーザーが指定されたルートの下にあるそのディレクトリにアクセスしようとしていると想定し、ルートが次の別の DirLister を作成します。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))

注: すべての変数アクセスをサブディレクトリ アクセスとして扱いたくないため、最初にその属性の基本クラスを確認します。そのような属性がない場合は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']
于 2011-12-13T17:37:20.447 に答える
0

何を求めているのかわかりませんが、これでうまくいきますか?

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']
于 2011-12-13T17:08:56.497 に答える