with NamedTemporaryFile(suffix='.shp').name as tmp_shp:
    df.to_file(tmp_shp)

Dans le code ci-dessus, j'obtiens cette erreur:

AttributeError: __enter__

Comment puis-je utiliser un fichier temporaire nommé à l'aide de l'instruction with? et comme tmp_shp n'est qu'un chemin, reste-t-il toujours disponible en dehors de with?

0
user308827 17 avril 2018 à 04:26

3 réponses

Meilleure réponse

L'attribut name est une chaîne; essayer d'y accéder dans l'instruction with en fait la ressource gérée (et str n'a pas de concept de gestion de contexte). Vous devez gérer le NamedTemporaryFile lui-même et accéder au name selon vos besoins:

with NamedTemporaryFile(suffix='.shp') as tmp_shp:
    df.to_file(tmp_shp.name)  # Access .name here, assuming you need a str

Si to_file accepte des objets de type fichier (je ne trouve pas de documents pour une telle méthode), vous éviterez d'utiliser .name du tout (dans l'une ou l'autre ligne).

Mise à jour: parce que vous êtes sous Windows, vous ne pouvez pas réellement ouvrir un fichier ouvert par NamedTemporaryFile avec delete=True (par défaut) jusqu'à ce que NamedTemporaryFile soit fermé (ce qui signifie que vous ne pouvez pas utiliser de données écrites dans ce descripteur de fichier, car il est supprimé et introduit une condition de concurrence même si vous l'utilisez uniquement pour générer un nom unique; le fichier est supprimé à ce stade, donc vous êtes vraiment en train de créer un nouveau fichier, mais quelqu'un d'autre pourrait vous précipiter pour créer ce fichier plus tard). Le mieux que je puisse suggérer ici est de l'utiliser sans support de suppression pour obtenir un nom unique, en l'enveloppant pour forcer la suppression vous-même, par exemple:

tmp_shp = None
try:
    with NamedTemporaryFile(suffix='.shp', delete=False) as tmp_shp:

        df.to_file(tmp_shp.name)  # Access .name here, assuming you need a str

        ... do any other stuff with the file ...
finally:
    if tmp_shp is not None:
        os.remove(tmp_shp.name)

Ouais, c'est moche. Il n'y a pas beaucoup de bonnes options ici; NamedTemporaryFile est fondamentalement cassé sous Windows.

1
ShadowRanger 17 avril 2018 à 03:17

Vous devez utiliser l'instruction with pour NamedTemporaryFile lui-même, mais pas son attribut name.

with NamedTemporaryFile(suffix='.shp') as tmp_file:
    df.to_file(tmp_file)  # As temp_file is a file object, I think to_file should work?

Et en tant que document officiel, tmp_file sera supprimé en dehors de with à moins que vous ne passiez delete=False à NamedTemporaryFile.

Cela signifie que vous devriez with NamedTemporaryFile(suffix='.shp', delete=False) as tmp_file:

1
Sraw 17 avril 2018 à 01:30

Vous utilisez l'attribut name comme gestionnaire de contexte. Essayer:

with NamedTemporaryFile(suffix='.shp') as tmp_shp:
    df.to_file(tmp_shp)
1
TwistedSim 17 avril 2018 à 01:30