为什么在解组JSON时字符串和[]字节的处理方式不同?(Why are string and []bytes treated differently when unmarshaling JSON?)
我从阅读文档中得到的理解是,
string
本质上是一个不可变的[]byte
,并且可以轻松地在两者之间进行转换。然而,当从JSON解组时,这似乎并不正确。 采用以下示例程序:
package main import ( "encoding/json" "fmt" ) type STHRaw struct { Hash []byte `json:"hash"` } type STHString struct { Hash string `json:"hash"` } func main() { bytes := []byte(`{"hash": "nuyHN9wx4lZL2L3Ir3dhZpmggTQEIHEZcC3DUNCtQsk="}`) stringHead := new(STHString) if err := json.Unmarshal(bytes, &stringHead); err != nil { return } rawHead := new(STHRaw) if err := json.Unmarshal(bytes, &rawHead); err != nil { return } fmt.Printf("String:\t\t%x\n", stringHead.Hash) fmt.Printf("Raw:\t\t%x\n", rawHead.Hash) fmt.Printf("Raw to string:\t%x\n", string(rawHead.Hash[:])) }
这给出了以下输出:
String: 6e7579484e397778346c5a4c324c3349723364685a706d67675451454948455a63433344554e437451736b3d Raw: 9eec8737dc31e2564bd8bdc8af77616699a0813404207119702dc350d0ad42c9 Raw to string: 9eec8737dc31e2564bd8bdc8af77616699a0813404207119702dc350d0ad42c9
相反,我希望每次都能获得相同的价值。
有什么不同?
My understanding from reading the documentation was that
string
is essentially an immutable[]byte
and that one can easily convert between the two.However when unmarshaling from JSON this doesn't seem to be true. Take the following example program:
package main import ( "encoding/json" "fmt" ) type STHRaw struct { Hash []byte `json:"hash"` } type STHString struct { Hash string `json:"hash"` } func main() { bytes := []byte(`{"hash": "nuyHN9wx4lZL2L3Ir3dhZpmggTQEIHEZcC3DUNCtQsk="}`) stringHead := new(STHString) if err := json.Unmarshal(bytes, &stringHead); err != nil { return } rawHead := new(STHRaw) if err := json.Unmarshal(bytes, &rawHead); err != nil { return } fmt.Printf("String:\t\t%x\n", stringHead.Hash) fmt.Printf("Raw:\t\t%x\n", rawHead.Hash) fmt.Printf("Raw to string:\t%x\n", string(rawHead.Hash[:])) }
This gives the following output:
String: 6e7579484e397778346c5a4c324c3349723364685a706d67675451454948455a63433344554e437451736b3d Raw: 9eec8737dc31e2564bd8bdc8af77616699a0813404207119702dc350d0ad42c9 Raw to string: 9eec8737dc31e2564bd8bdc8af77616699a0813404207119702dc350d0ad42c9
Instead I would have expected to receive the same value each time.
What is the difference?
原文:
最满意答案
基本上你问的是如何从shell中分离程序...这里有几个选项
- ./scriptname.py> / dev / null 2>&1&#将程序发送到后台
- 使用gnu-screen (或类似的)...通过屏幕运行你的程序,你可以在重新登录时重新启动它
- 正确地对您的程序进行Daemonize
更新:
最近我没有在python中编写一个守护进程。 分叉两次或使用守护程序库的日子似乎远远落后于我们。 我目前使用supervisord ,并听说过马戏团的好消息。 这些只是可用于部署python守护进程的一小部分额外选项。
Basically you are asking about how to detach the program from your shell ... here is a few options
- ./scriptname.py >/dev/null 2>&1 & # sends the program to the background
- Use gnu-screen (or similar) ... run your program via screen and you can bring it back up when you log back in
- Daemonize your program properly
Update:
Recently I have not written a single daemon in python. The days of forking twice or using a daemon library seem to be well behind us. I currently use supervisord and have heard good things about circus. These are just a small set of extra options you can use to deploy python daemons.
相关问答
更多-
用以下回调配置http服务器会很好: 在启动服务器之前 启动服务器后 在停止服务器之前 停止服务器后 请记住,在套接字开始监听的时刻,操作系统将开始接受和排队TCP连接,这是在BaseHTTPServer的构造函数中完成的,因此如果您想在启动服务器之前执行冗长的任务,最好在OS开始接受连接。 有一个server_activate()方法可以调用socket.listen() ,所以最好重写它。 同样,操作系统将继续接受连接,直到调用socket.close()为止,所以如果你想能够定义一个能够阻止自己关闭的 ...
-
是的, BaseServer.shutdown()方法是线程安全的。 serve_forever方法一直有效,直到设置了shutdown标志,并且shutdown()的任务是设置该标志。 该方法在docstring中声明: 阻塞直到循环结束。 当serve_forever()在另一个线程中运行时,必须调用它,否则它将死锁。 请注意,这与GIL无关; 这只限制了Python进程可以有效利用C扩展和I / O之外的核心数量。 Yes, the BaseServer.shutdown() method is th ...
-
如何让HTTPServer通过do_GET返回自己的类?(How to get HTTPServer to pass my own class back with do_GET's?)[2022-03-25]
这似乎工作: def run_server(state_database, port): server_address = ('', port) handlerclass = makehandlerclassfordb(state_database) httpserver = HTTPServer(server_address, handlerclass) httpserver.serve_forever() def makehandlerclassfordb(sta ... -
所以你可能想参考这个https://docs.python.org/2/library/basehttpserver.html#more-examples你必须定义自己的keep_running()条件。 以下是我的样本: import BaseHTTPServer httpd = BaseHTTPServer.HTTPServer(('', 8000), BaseHTTPServer.BaseHTTPRequestHandler) mylist = range(10) while mylist: ...
-
从文档中可以看出, TCPServer基类的contextmanager协议( with ... )形式(因此在python3.6中添加了TCPServer。这在python3.5中不可用) 版本3.6中已更改:添加了对上下文管理器协议的支持。 退出上下文管理器相当于调用server_close() 。 幸运的是,您可以使用以前的方法。 这大致意味着将您的with语句转换为简单的赋值: httpd = socketserver.TCPServer(("", PORT), Handler) print("se ...
-
事实上, waitress是可能的 先用bin/pip install waitress ,然后查看你的proxy.ini并编辑server:main部分,使用waitress而不是paste.httpserver [server:main] use = egg:waitress#main unix_socket = var/run/diazo.sock 瞧。 Paster现在在unix套接字上提供HTTP服务。 Indeed, it is possible with waitress First bin ...
-
您的css和图像无法加载的原因是您的处理程序不知道如何处理这些文件的请求。 这是一个简单的例子,从您链接到的问题中的nosklo的答案中复制(并调整了abit)。 def do_GET(self): try: if self.path in ("", "/"): filepath = "html/bad.html" else: filepath = self.path.lstrip("/") f = o ...
-
这属于TCPServer文档的“高级多进程”类别。 您需要显式调用fork_processes而不是让其中一个服务器执行它。 重新安排你的安装调用,以便在fork之前绑定所有套接字,然后将它们添加到服务器之后(根据经验,你希望在fork之前尽可能少地执行): data_sock = tornado.netutil.bind_sockets(4242) http_sock = tornado.netutil.bind_sockets(8080) tornado.process.fork_processes( ...
-
ConcurrentLogHandler可以由logger.handlers [0] .doRollover()确实转存。 我遇到的问题是我先前使用了RotatingLogHandler,并且.lock文件保留在日志目录中,防止它被翻转。 删除锁定文件并将ConcurrentLogHandler保持为首选处理程序(而不是RotatingLogHandler)可以解决问题。 ConcurrentLogHandler can be rolled over by logger.handlers[0].doRoll ...
-
基本上你问的是如何从shell中分离程序...这里有几个选项 ./scriptname.py> / dev / null 2>&1&#将程序发送到后台 使用gnu-screen (或类似的)...通过屏幕运行你的程序,你可以在重新登录时重新启动它 正确地对您的程序进行Daemonize 更新: 最近我没有在python中编写一个守护进程。 分叉两次或使用守护程序库的日子似乎远远落后于我们。 我目前使用supervisord ,并听说过马戏团的好消息。 这些只是可用于部署python守护进程的一小部分额外选项 ...