<p>我假设你希望subdir像属性一样可访问,你可以通过两种方式来实现</p>
<ul>
<li>浏览文件列表并动态创建变量</li>
<li>钩住属性访问并根据需要正确返回列表器</li>
</ul>
<p>我更喜欢第二种方法,因为它很懒,更好,更容易实现</p>
<pre><code>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
</code></pre>
<p>输出:</p>
^{pr2}$
<p>你可以改进这有更好的错误检查等</p>
<p><strong>代码说明:</strong>这基本上是目录的递归列表,因此<code>DirLister</code>对象列出给定根目录下的文件,如果使用虚线符号访问某个变量,它将返回一个DirLister,假设该属性是根目录下的文件夹。因此,如果我们尝试一步一步地创建<code>DirLister</code>类,它将更加清晰</p>
<p>1-一个简单的<code>DirLister</code>,它只列出它下面的文件/文件夹</p>
<pre><code>class DirLister(object):
def __init__(self, root):
self.root = root
self._list = os.listdir(self.root)
</code></pre>
<p>2-我们的简单列表器只列出一级深的文件,如果我们想在子文件夹下获取文件服务器,我们可以挂接到<code>__getattr__</code>,当使用<code>obj.varname</code>时,这个函数用varname调用。所以,如果dir-lister没有名为varname的属性,我们假设用户试图访问给定根目录下的目录,那么我们创建另一个DirLister,它的根是<code>root+subdirname</code></p>
<pre><code>def __getattr__(self, name):
try:
var = super(DirLister).__getattr__(self, name)
return var
except AttributeError:
return DirLister(os.path.join(self.root, name))
</code></pre>
<p>注意:首先我们检查该属性的基类,因为我们不想将所有变量访问都视为sub dir访问,如果没有这样的属性,因此<code>AttributeError</code>,那么我们为sub folder创建一个新的DirLister。在</p>
<p>3-为了改进代码,即使用户没有要求,我们也不会列出所有文件夹,我们只在用户需要时列出,因此使用了<code>load</code>方法</p>
<pre><code>def _load(self):
if self._list is not None:
return
self._list = os.listdir(self.root) # list root someway
</code></pre>
<p>因此,如果还没有列出,这个方法将列出dir,当我们最终需要它时,例如在打印列表时,应该调用它</p>
<p>编辑:正如OP所要求的,这里是递归列出整棵树的替代方法,尽管我强烈建议不要使用它</p>
<pre><code>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
</code></pre>
<p>输出:</p>
<pre><code>['conf.avail', 'conf.d', 'fonts.conf', 'fonts.dtd']
</code></pre>