【问题标题】:write utf-8 content in files / python 3在文件/python 3中写入utf-8内容
【发布时间】:2018-07-18 00:13:24
【问题描述】:

第 1001 次又是关于 utf-8 的问题。请不要将此问题标记为重复,因为我在其他地方找不到答案。

几个月以来,我一直在成功使用以下小脚本(我知道这可能会有所改进),它为我提供了一个简单的数据库功能。但我写它是为了非常简单的数据存储,比如本地配置和身份验证数据,让我们说不是为了从 cookie 中知道的更复杂的内容。它对我有用,直到我第一次尝试存储非拉丁字符。

在以下脚本中,我已经添加了 import codecs 内容,包括更改后的行 f = codecs.open(file, 'w', 'utf-8')。不知道这是否是正确的方法。

有人能告诉我诀窍吗?假设“John Doe”是法语,“John Doé”,我该如何存储它?

类本身(要导入)

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import os, errno
import json
import codecs

class Ddpos:

    def db(self,table,id,col=''):
        table = '/Users/michag/Documents/ddposdb/'+table

        try:
            os.makedirs(table)
            os.chmod(table, 0o755)
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise

        file = table+'/'+id+'.txt'

        if not os.path.isfile(file):
            f = codecs.open(file, 'w', 'utf-8')
            f.write('{}')
            f.close()

        f = codecs.open(file, 'r', 'utf-8')
        r = json.loads(f.readline().strip())
        f.close()

        if isinstance(col, str) and len(col) > 0:
            if col in r:
                return json.dumps(r[col])
            else:
                return ''

        elif isinstance(col, list) and len(col) > 0:
            res = {}
            for el in range(0,len(col)):
                if col[el] in r:
                    res[col[el]] = r[col[el]]
            return json.dumps(res)

        elif isinstance(col, dict) and len(col) > 0:
            for el in col:
                r[el] = col[el]
            f = codecs.open(file, 'w', 'utf-8')
            f.write(json.dumps(r))
            f.close()
            return json.dumps(r)

        else:
            return json.dumps(r)

ddpos = Ddpos()

调用/用法

#!/usr/bin/python3
# -*- coding: utf-8 -*-

from ddpos import *

# set values and return all values as dict
print ('1.: '+ddpos.db('cfg','local',{'admin':'John Doé','email':'johndoe@email.com'}))

# return all values as dict
print ('2.: '+ddpos.db('cfg','local'))

# return one value as string
print ('3.: '+ddpos.db('cfg','local','email'))

# return two or more values as dict
print ('4.: '+ddpos.db('cfg','local',['admin','email']))

如果是“John Doe”,它会打印并存储它

1.: {"admin": "John Doe", "email": "johndoe@email.com"}
2.: {"admin": "John Doe", "email": "johndoe@email.com"}
3.: "johndoe@email.com"
4.: {"admin": "John Doe", "email": "johndoe@email.com"}

如果是法国人“John Doé”

1.: {"email": "johndoe@email.com", "admin": "John Do\u00e9"}
2.: {"email": "johndoe@email.com", "admin": "John Do\u00e9"}
3.: "johndoe@email.com"
4.: {"email": "johndoe@email.com", "admin": "John Do\u00e9"}

对我来说,学习和理解它是如何工作的以及为什么或为什么不更重要,但要知道已经有课程可以为我完成这项工作。感谢您的支持。

【问题讨论】:

  • “因为我在别处找不到答案” 并不是不将其作为重复项关闭的真正理由。
  • 除此之外...怎么了?输出在我看来 100% 正确。
  • @Tomalak 好的,假设输出按预期工作>为您 :-)"admin": "John Do\u00e9",以后如何使用它?
  • 因此,您的每个“表”都是一个包含 dict 的 json 转储的文件。但是当您检索一个值时,您读取该字典,解析它,提取您想要的值,再次将其转储到 json 并返回它。所以你要 dict -> json -> dict -> json。你永远不会再得到一个字典,你总是得到一个字符串。我认为如果您将json.dumps() 放在任何有return json.dumps(...) 的地方会更有意义
  • @mata 是的,你是对的。除了f.write(json.dumps(r)) 之外,我放弃了它,它可以工作。它仍然存储为John Do\u00e9,但return 的输出直接是read 提供的,是正确的:2.: {'email': 'johndoe@email.com', 'admin': 'John Doé'}。竖起大拇指,感谢和来自 ddlab 的 1+

标签: python-3.x file utf-8


【解决方案1】:

在主持人 deceze 之后,我用用户 mata 和 python3 本身的凭据回答了我自己的问题。

这是“新”脚本。可怜的法国人现在改名为“J€hn Doéß”,他还活着。

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import os, errno
import json

class Ddpos:

    def db(self,table,id,col=''):
        table = '/Users/michag/Documents/ddposdb/'+table

        try:
            os.makedirs(table)
            os.chmod(table, 0o755)
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise

        file = table+'/'+id+'.txt'

        if not os.path.isfile(file):
            f = open(file, 'w')
            f.write('{}')
            f.close()

        f = open(file, 'r')
        r = json.loads(f.readline().strip())
        f.close()

        if isinstance(col, str) and len(col) > 0:
            if col in r:
                return r[col]
            else:
                return ''

        elif isinstance(col, list) and len(col) > 0:
            res = {}
            for el in range(0,len(col)):
                if col[el] in r:
                    res[col[el]] = r[col[el]]
            return res

        elif isinstance(col, dict) and len(col) > 0:
            for el in col:
                r[el] = col[el]
            f = open(file, 'w')
            f.write(json.dumps(r))
            f.close()
            return r

        else:
            return r

ddpos = Ddpos()

【讨论】:

    【解决方案2】:

    更新

    我做了一些改进。现在存储的 dict 是人类可读的(对于像我这样的非信徒)并且不区分大小写。这个排序过程肯定会消耗一些性能,但是,嘿,我将使用只读过程比写入过程多百倍。

    现在存储的字典看起来像这样:

    {
            "auth_descr": "dev unit, office2",
            "auth_email": "me@myemail.com",
            "auth_key": "550e3 **shortened sha256** d73b1",
            "auth_unit_id": "2.3.1",
            "vier": "44é", # utf-8 example
            "Vjier": "vier44" # uppercase example
    }
    

    我不知道我在早期版本中哪里出错了,但是如果你看看 utf-8 示例。 “é”现在存储为“é”而不是“\u00e9”。

    这个类现在看起来像这样(有细微的变化)

    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    
    import os, errno
    import json
    
    class Ddpos:
    
            def db(self,table,id,col=''):
                    table = '/ddpos/db/'+table
    
                    try:
                            os.makedirs(table)
                            os.chmod(table, 0o755)
                    except OSError as e:
                            if e.errno != errno.EEXIST:
                                    raise
    
                    file = table+'/'+id+'.txt'
    
                    if not os.path.isfile(file):
                            f = open(file, 'w', encoding='utf-8')
                            f.write('{}')
                            f.close()
    
                    f = open(file, 'r', encoding='utf-8')
                    r = json.loads(f.read().strip())
                    f.close()
    
                    if isinstance(col, str) and len(col) > 0:
                            if col in r:
                                    return r[col]
                            else:
                                    return ''
    
                    elif isinstance(col, list) and len(col) > 0:
                            res = {}
                            for el in range(0,len(col)):
                                    if col[el] in r:
                                            res[col[el]] = r[col[el]]
                            return res
    
                    elif isinstance(col, dict) and len(col) > 0:
                            for el in col:
                                    r[el] = col[el]
                            w = '{\n'
                            for key in sorted(r, key=lambda y: y.lower()):
                                    w += '\t"%s": "%s",\n' % (key, r[key])
                            w = w[:-2]+'\n'
                            w += '}'
                            f = open(file, 'w', encoding='utf-8')
                            f.write(w)
                            f.close()
                            return r
    
                    else:
                            return r
    
    ddpos = Ddpos()
    

    【讨论】:

      猜你喜欢
      • 2010-10-30
      • 1970-01-01
      • 2011-05-06
      • 1970-01-01
      • 2020-08-09
      • 1970-01-01
      • 2010-10-04
      • 2015-04-12
      相关资源
      最近更新 更多