20 Stimmen

Schließen Sie das gesamte Verzeichnis in python setup.py data_files ein

Der data_files-Parameter für das Setup nimmt Eingaben im folgenden Format an:

setup(...
    data_files = [(Zielverzeichnis, [Liste der dort abzulegenden Dateien])]
    ....)

Gibt es einen Weg, um ein ganzes Verzeichnis mit Daten anzugeben, so dass ich nicht jedes einzelne File benennen und aktualisieren muss, wenn ich die Implementierung in meinem Projekt ändere?

Ich habe versucht, os.listdir() zu verwenden, aber ich weiß nicht, wie ich das mit relativen Pfaden machen soll. Ich konnte os.getcwd() oder os.realpath(__file__) nicht verwenden, da diese nicht korrekt auf mein Repository-Wurzelverzeichnis zeigen.

23voto

Pete Baughman Punkte 2787

Karelv hat die richtige Idee, aber um die gestellte Frage direkter zu beantworten:

from glob import glob

setup(
    #...
    data_files = [
        ('zielverzeichnis_1', glob('quellverzeichnis/*')), # Dateien nur im Quellverzeichnis - nicht rekursiv
        ('zielverzeichnis_2', glob('verschachteltes_quellverzeichnis/**/*', rekursiv=True)), # Unterordner einschließen - rekursiv
        # usw...
    ],
    #...
)

4voto

karelv Punkte 706
import glob

for filename in glob.iglob('inner_dir/**/*', recursive=True):
    print (filename)

Wenn Sie dies tun, erhalten Sie direkt eine Liste von Dateien relativ zum aktuellen Verzeichnis.

2voto

Paul Mundt Punkte 459

Ich hatte das gleiche Problem mit Verzeichnissen, die verschachtelte Unterverzeichnisse enthalten. Die glob-Lösungen haben nicht funktioniert, da sie das Verzeichnis in die Liste eingeschlossen haben, was das Setup zum Absturz gebracht hätte. In Fällen, in denen ich übereinstimmende Verzeichnisse ausgeschlossen habe, hat es sie immer noch alle im gleichen Verzeichnis abgelegt, was auch nicht das war, was ich wollte. Letztendlich bin ich einfach auf os.walk() zurückgefallen:

def generate_data_files():
    data_files = []
    data_dirs = ('data', 'plugins')
    for path, dirs, files in chain.from_iterable(os.walk(data_dir) for data_dir in data_dirs):
        install_dir = os.path.join(sys.prefix, 'share//' + path)    
        list_entry = (install_dir, [os.path.join(path, f) for f in files if not f.startswith('.')])
        data_files.append(list_entry)

    return data_files

und dann data_files=generate_data_files() im setup()-Block setzen.

1voto

deadbeef404 Punkte 626

Ich weiß nicht, wie das mit relativen Pfaden gemacht werden soll

Sie müssen den Pfad des Verzeichnisses zuerst erhalten, also...

Angenommen, Sie haben diese Verzeichnisstruktur:

cur_directory
|- setup.py
|- inner_dir
   |- file2.py

Um das Verzeichnis der aktuellen Datei zu erhalten (in diesem Fall setup.py), verwenden Sie dies:

cur_directory_path = os.path.abspath(os.path.dirname(__file__))

Dann, um einen Verzeichnispfad relativ zum current_directory zu erhalten, fügen Sie einfach einige andere Verzeichnisse hinzu, z. B.:

inner_dir_path = os.path.join(cur_directory_path, 'inner_dir')

Wenn Sie ein Verzeichnis nach oben wechseln möchten, verwenden Sie einfach "..", zum Beispiel:

parent_dir_path = os.path.join(current_directory, '..')

Wenn Sie diesen Pfad haben, können Sie os.listdir verwenden

Zur Vollständigkeit:

Wenn Sie den Pfad einer Datei, in diesem Fall "file2.py" relativ zu setup.py möchten, könnten Sie dies tun:

file2_path = os.path.join(cur_directory_path, 'inner_dir', 'file2.py')

1voto

omerts Punkte 8026

Basierend auf der Antwort von @Paul Mundt, die ich umschreiben musste, ist dies, was für mich funktioniert hat:

# Iteriere durch alle Dateien und Unterverzeichnisse
# um das Daten-Dateien-Array aufzubauen
def generate_data_files(share_path, dir):
    data_files = []

    for path, _, files in os.walk(dir):
        list_entry = (share_path + path, [os.path.join(path, f) for f in files if not f.startswith('.')])
        data_files.append(list_entry)

    return data_files

Beispielverwendung:

data_files=[
        ('share/' + package_name + '/maps', glob('maps/*')),
        ('share/' + package_name + '/world', glob('world/*'))
    ] + generate_data_files('share/' + package_name + '/', 'meshes'),

Dies fügt den Ordner meshes unter share mit allen Dateien und Unterordnern rekursiv hinzu. Bildbeschreibung hier eingeben

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X