Vraag Absoluut pad van een bestandsobject


Dit is eerder besproken in StackOverflow: ik probeer een goede manier te vinden om het absolute pad van een bestandsobject te vinden, maar ik wil dat het bestand robuust is voor os.chdir(), kan dus niet gebruiken

f = file('test')
os.path.abspath(f.name)

In plaats daarvan vroeg ik me af of het volgende een goede oplossing is - in feite uitbreiding van de bestandsklasse zodat bij opening het absolute pad van het bestand wordt opgeslagen:

class File(file):

    def __init__(self, filename, *args, **kwargs):
        self.abspath = os.path.abspath(filename)
        file.__init__(self, filename, *args, **kwargs)

Dan kan men het doen

f = File('test','rb')
os.chdir('some_directory')
f.abspath # absolute path can be accessed like this

Zijn er risico's om dit te doen?


14
2018-03-16 22:41


oorsprong


antwoorden:


Een belangrijk risico is dat, als het bestand eenmaal is geopend, het proces met dat bestand omgaat door zijn bestandsdescriptor, niet zijn pad. Op veel besturingssystemen het pad van het bestand kan met een ander proces worden gewijzigd (door een mv bewerking in een niet-gerelateerd proces, bijvoorbeeld) en de bestandsdescriptor is nog steeds geldig en verwijst naar hetzelfde bestand.

Ik profiteer hier vaak van door bijvoorbeeld een groot bestand te downloaden en vervolgens te beseffen dat het doelbestand niet is waar ik het wil hebben, en naar een afzonderlijke shell te springen en het naar de juiste locatie te verplaatsen - terwijl de de download gaat door zonder onderbreking.

Het is dus een slecht idee om afhankelijk te zijn van het pad dat hetzelfde blijft voor de duur van het proces, wanneer een dergelijke garantie niet wordt gegeven door het besturingssysteem.


13
2018-03-16 23:15



Het hangt er vanaf waar je het nodig hebt.

Zolang u de beperkingen begrijpt - iemand kan het bestand tussentijds verplaatsen, hernoemen of hard-linken - zijn er voldoende geschikte toepassingen voor. Misschien wilt u het bestand verwijderen als u er klaar mee bent of als er iets fout gaat tijdens het schrijven (bijv. Gcc doet dit bij het schrijven van bestanden):

f = File(path, "w+")
try:
    ...
except:
    try:
        os.unlink(f.abspath)
    except OSError: # nothing we can do if this fails
        pass
    raise

Als je alleen het bestand in gebruikersberichten wilt kunnen identificeren, is er al file.name. Het is onmogelijk om dit (betrouwbaar) voor iets anders te gebruiken, helaas; er is geen manier om onderscheid te maken tussen een bestandsnaam "<stdin>"en sys.stdin, bijvoorbeeld.

(Je zou eigenlijk niet van een ingebouwde klasse hoeven af ​​te leiden om er attributen aan toe te voegen; dat is gewoon een lelijke, inconsistente gril van Python ...)


1
2018-03-17 17:00