質問
すべてのサブディレクトリでindex.tplをindex.htmlにコピーする単純なPythonスクリプトを作成しようとしています(いくつかの例外はあります)。
サブディレクトリのリストを取得しようとすると、動きが取れなくなります。
解決
import os
def get_immediate_subdirectories(a_dir):
return [name for name in os.listdir(a_dir)
if os.path.isdir(os.path.join(a_dir, name))]
他のヒント
glob
に言及している人がいないのはなぜですか? glob
を使用すると、Unixスタイルのパス名展開を使用できます。また、複数のパス名を見つける必要があるほとんどすべての機能を使用できます。非常に簡単になります:
from glob import glob
paths = glob('*/')
glob
は(unixのように)最後のスラッシュでディレクトリを返しますが、ほとんどの path
ベースのソリューションは最後のスラッシュを省略します。
チェック" 現在のディレクトリ内のすべてのサブディレクトリのリスト"。
Python 3バージョンは次のとおりです。
import os
dir_list = next(os.walk('.'))[1]
print(dir_list)
import os, os.path
ディレクトリ内の(フルパス)直下のサブディレクトリを取得するには:
def SubDirPath (d):
return filter(os.path.isdir, [os.path.join(d,f) for f in os.listdir(d)])
最新の(最新の)サブディレクトリを取得するには:
def LatestDirectory (d):
return max(SubDirPath(d), key=os.path.getmtime)
os.walk
はこの状況であなたの友人です。
ドキュメントからの直線:
walk()は、ツリーをトップダウンまたはボトムアップでたどることにより、ディレクトリツリーにファイル名を生成します。ディレクトリtopをルートとするツリー内の各ディレクトリ(top自体を含む)に対して、3つのタプル(dirpath、dirnames、filenames)が生成されます。
このメソッドは、すべてを一度にうまく実行します。
from glob import glob
subd = [s.rstrip("/") for s in glob(parent_dir+"*/")]
TwistedのFilePathモジュールの使用:
from twisted.python.filepath import FilePath
def subdirs(pathObj):
for subpath in pathObj.walk():
if subpath.isdir():
yield subpath
if __name__ == '__main__':
for subdir in subdirs(FilePath(".")):
print "Subdirectory:", subdir
このためにTwistedのライブラリを使用する利点は何かとコメントする人もいるので、ここでの元の質問を少し超えます。
ドキュメントの改善 FilePathの利点を説明するブランチ内。読みたくなるかもしれません。
この例では、具体的には、標準ライブラリバージョンとは異なり、この関数はインポートなしで実装できます。 「サブディレクトリ」関数は、引数のみで動作するという点で完全に汎用的です。標準ライブラリを使用してファイルをコピーおよび移動するには、" open
"に依存する必要があります。組み込み、" listdir
&quot ;、おそらく" isdir
"または" os.walk
"または" shutil.copy
"。たぶん" os.path.join
"も。実際のファイルを識別するために引数に文字列を渡す必要があるという事実は言うまでもありません。各ディレクトリの" index.tpl"をコピーする完全な実装を見てみましょう。 " index.html"へ:
def copyTemplates(topdir):
for subdir in subdirs(topdir):
tpl = subdir.child("index.tpl")
if tpl.exists():
tpl.copyTo(subdir.child("index.html"))
"サブディレクトリ"上記の関数は、 FilePath
のようなオブジェクトで機能します。これは、とりわけ、 ZipPath
オブジェクトを意味します。残念ながら ZipPath
は現在読み取り専用ですが、書き込みをサポートするために拡張できます。
テスト目的で独自のオブジェクトを渡すこともできます。ここで提案されているos.pathを使用するAPIをテストするには、インポートされた名前と暗黙的な依存関係を確認し、一般的に黒魔術を実行してテストを機能させる必要があります。 FilePathを使用すると、次のようになります。
class MyFakePath:
def child(self, name):
"Return an appropriate child object"
def walk(self):
"Return an iterable of MyFakePath objects"
def exists(self):
"Return true or false, as appropriate to the test"
def isdir(self):
"Return true or false, as appropriate to the test"
...
subdirs(MyFakePath(...))
vmware仮想マシンを移動するためのコードをいくつか書いたところ、 os.path
と shutil
を使用してサブディレクトリ間のファイルコピーを実現しました。
def copy_client_files (file_src, file_dst):
for file in os.listdir(file_src):
print "Copying file: %s" % file
shutil.copy(os.path.join(file_src, file), os.path.join(file_dst, file))
それほどエレガントではありませんが、機能します。
1つの方法を次に示します。
import os
import shutil
def copy_over(path, from_name, to_name):
for path, dirname, fnames in os.walk(path):
for fname in fnames:
if fname == from_name:
shutil.copy(os.path.join(path, from_name), os.path.join(path, to_name))
copy_over('.', 'index.tpl', 'index.html')
def get_folders_in_directories_recursively(self, directory, index=0):
folder_list = list()
parent_directory = directory
for path, subdirs, _ in os.walk(directory):
if not index:
for sdirs in subdirs:
folder_path = "{}/{}".format(path, sdirs)
folder_list.append(folder_path)
elif path[len(parent_directory):].count('/') + 1 == index:
for sdirs in subdirs:
folder_path = "{}/{}".format(path, sdirs)
folder_list.append(folder_path)
return folder_list
次の関数は次のように呼び出すことができます。
get_folders_in_directories_recursively(directory、index = 1)->第1レベルのフォルダーのリストを提供します
get_folders_in_directories_recursively(directory)->すべてのサブフォルダを提供します
使用する path.py ライブラリに言及する必要があります。非常に頻繁に。
直接のサブディレクトリを取得すると、次のように簡単になります。
my_dir.dirs()
完全な動作例は次のとおりです。
from path import Path
my_directory = Path("path/to/my/directory")
subdirs = my_directory.dirs()
NB:パスは文字列のサブクラスであるため、my_directoryは依然として文字列として操作できますが、パスを操作するための便利なメソッドを提供します
import glob
import os
def child_dirs(path):
cd = os.getcwd() # save the current working directory
os.chdir(path) # change directory
dirs = glob.glob("*/") # get all the subdirectories
os.chdir(cd) # change directory to the script original location
return dirs
child_dirs
関数はディレクトリのパスを取り、その中の即時サブディレクトリのリストを返します。
dir
|
-- dir_1
-- dir_2
child_dirs('dir') -> ['dir_1', 'dir_2']
import pathlib
def list_dir(dir):
path = pathlib.Path(dir)
dir = []
try:
for item in path.iterdir():
if item.is_dir():
dir.append(item)
return dir
except FileNotFoundError:
print('Invalid directory')