मैं पाइथन 2 में पायथन 3 tokenize.detect_encoding()
function उधार लेता हूं, पाइथन 2 अपेक्षाओं से मेल खाने के लिए थोड़ा समायोजित करता हूं। मैंने फ़ाइल नाम स्वीकार करने के लिए फ़ंक्शन हस्ताक्षर को बदल दिया है और अब तक पढ़ने वाली लाइनों को शामिल करने को छोड़ दिया है; आप अपने USECASE के लिए उन की जरूरत नहीं है:
import re
from codecs import lookup, BOM_UTF8
cookie_re = re.compile(r'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)')
blank_re = re.compile(br'^[ \t\f]*(?:[#\r\n]|$)')
def _get_normal_name(orig_enc):
"""Imitates get_normal_name in tokenizer.c."""
# Only care about the first 12 characters.
enc = orig_enc[:12].lower().replace("_", "-")
if enc == "utf-8" or enc.startswith("utf-8-"):
return "utf-8"
if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \
enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")):
return "iso-8859-1"
return orig_enc
def detect_encoding(filename):
bom_found = False
encoding = None
default = 'ascii'
def find_cookie(line):
match = cookie_re.match(line)
if not match:
return None
encoding = _get_normal_name(match.group(1))
try:
codec = lookup(encoding)
except LookupError:
# This behaviour mimics the Python interpreter
raise SyntaxError(
"unknown encoding for {!r}: {}".format(
filename, encoding))
if bom_found:
if encoding != 'utf-8':
# This behaviour mimics the Python interpreter
raise SyntaxError(
'encoding problem for {!r}: utf-8'.format(filename))
encoding += '-sig'
return encoding
with open(filename, 'rb') as fileobj:
first = next(fileobj, '')
if first.startswith(BOM_UTF8):
bom_found = True
first = first[3:]
default = 'utf-8-sig'
if not first:
return default
encoding = find_cookie(first)
if encoding:
return encoding
if not blank_re.match(first):
return default
second = next(fileobj, '')
if not second:
return default
return find_cookie(second) or default
मूल कार्य की तरह, ऊपर समारोह दो पंक्तियों स्रोत फ़ाइल से अधिकतम पढ़ता है, और एक SyntaxError
अपवाद बढ़ा देंगे अगर कुकी में एन्कोडिंग अमान्य है या यूटीएफ -8 नहीं है जबकि यूटीएफ -8 बीओएम मौजूद है।
डेमो:
>>> import tempfile
>>> def test(contents):
... with tempfile.NamedTemporaryFile() as f:
... f.write(contents)
... f.flush()
... return detect_encoding(f.name)
...
>>> test('# -*- coding: utf-8 -*-\n')
'utf-8'
>>> test('#!/bin/env python\n# -*- coding: latin-1 -*-\n')
'iso-8859-1'
>>> test('import this\n')
'ascii'
>>> import codecs
>>> test(codecs.BOM_UTF8 + 'import this\n')
'utf-8-sig'
>>> test(codecs.BOM_UTF8 + '# encoding: latin-1\n')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in test
File "<string>", line 37, in detect_encoding
File "<string>", line 24, in find_cookie
SyntaxError: encoding problem for '/var/folders/w0/nl1bwj6163j2pvxswf84xcsjh2pc5g/T/tmpxsqH8L': utf-8
>>> test('# encoding: foobarbaz\n')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in test
File "<string>", line 37, in detect_encoding
File "<string>", line 18, in find_cookie
SyntaxError: unknown encoding for '/var/folders/w0/nl1bwj6163j2pvxswf84xcsjh2pc5g/T/tmpHiHdG3': foobarbaz
स्रोत
2016-07-14 12:50:28
यह बहुत संभव है कि एन्कोडिंग जानकारी 'pyc' के संकलन के बाद खो जाता है। आपको सीधे 'py' फ़ाइल को पार्स करने की आवश्यकता हो सकती है। – gdlmx
ध्यान दें कि 'sys.getdefaultencoding() 'में कुछ भी नहीं है * पाइथन स्रोत कोड को कैसे डीकोड किया गया है। –