[python] Detekce kodovani zadaneho vstupu (bylo RE: soubor v jiné zankové sadě)
Petr Prikryl
PrikrylP na skil.cz
Pátek Září 30 09:14:19 CEST 2005
Navrhuji další úpravu "mazacího" skriptu...
Ve funkci smazat se konverze na unicode provádí dvakrát:
geon...
>
> def smazat(cesta):
> print os.listdir(cesta)
> print unicode(cesta,"cp1250"), "---> OPRAVDU SMAZAT? (a/n): ",
> ano=raw_input()
> if ano.lower()!='a':
> return False
> for root, dirs, files in os.walk(unicode(cesta,"cp1250"), topdown=False):
> for file in files:
> soubor=os.path.join(root, file)
> os.chmod(soubor,stat.S_IWRITE)
> os.remove(soubor)
> if root != cesta: # mazani adresaru krome toho zadaneho...
> os.chmod(root,stat.S_IWRITE)
> print root
> os.rmdir(root)
> return True
Dalo by se to sice udělat jednou (trošku se to zpřehlední).
Kromě toho bych upravil test na "ano" (první písmeno
zadaného řetězce se porovnává s více možnostmi):
def smazat2(cesta):
cesta = unicode(cesta, 'cp1250')
print os.listdir(cesta)
print cesta, "---> OPRAVDU SMAZAT? (a/n): ",
odpoved=raw_input()[0]
if odpoved not in 'aAyY':
return False
for root, dirs, files in os.walk(cesta, topdown=False):
for file in files:
soubor=os.path.join(root, file)
os.chmod(soubor,stat.S_IWRITE)
os.remove(soubor)
if root != cesta: # mazaní adresaru krome toho zadaneho...
os.chmod(root,stat.S_IWRITE)
print root
os.rmdir(root)
return True
Jenže tohle nebude fungovat z DOSového okna (kódování
cp852 -- viz dále). Doporučuji upravit funkci smazat()
tak, aby se cesta přímo z venku zadávala v unicode.
To znamená, že funkce pouze ověří, že tomu tak je:
def smazat3(cesta):
assert(isinstance(cesta, unicode))
print os.listdir(cesta)
print cesta, "---> OPRAVDU SMAZAT? (a/n): ",
odpoved=raw_input()[0]
if odpoved not in 'aAyY':
return False
for root, dirs, files in os.walk(cesta, topdown=False):
for file in files:
soubor=os.path.join(root, file)
os.chmod(soubor,stat.S_IWRITE)
os.remove(soubor)
if root != cesta: # mazaní adresaru krome toho zadaneho...
os.chmod(root,stat.S_IWRITE)
print root
os.rmdir(root)
return True
Převod na unicode se pak udělá před voláním smazat3(),
protože to logicky patří mimo tuto funkci.
Kdysi mě velmi hnětlo, že jsem musel moduly používající
raw_input() přizpůsobovat tomu, jestli je spouštím
prostřednictvím nějakého windowsovského okna, nebo
prostřednictvím DOSového okna. Nelíbilo se mi, že
někde musím při konverzi do unicode psát natvrdo
'cp1250' (z DOSového okna se používá jiné kódování,
než ve windowsovém okně -- např. v konzole IDLE).
Jenže zrovna v tomto případě to jde udělat šikovněji.
Tahle informace je ukryta pod sys.stdin.encoding.
Příklad v DOS:
>>> import sys
>>> sys.stdin.encoding
'cp852'
Příklad v IDLE:
>>> import sys
>>> sys.stdin.encoding
'cp1250'
To znamená, že toho můžu využívat při načítání
cesty (před voláním smazat3()) a skript bude
fungovat jak z dosového okna, tak z windowsového.
Nikde se v něm nevyskytuje 'cp1250' nebo něco
podobného (definice použitého kódování v hlavičce
souboru s tím nesouvisí, tu nepočítám):
def main():
print 'Zadej cestu:',
cesta = unicode(raw_input(), sys.stdin.encoding)
smazat3(cesta)
if __name__ == '__main__':
main()
pepr
--
Petr Prikryl (prikrylp at skil dot cz)
Další informace o konferenci Python