前段时间学习一个 Python 开源项目的时候看到了使用 pickle 库的代码,感觉反序列出来后的一些代码和以前熟悉的语言不太一样就了解了一下 pickle 库,确实是不一样,感觉是眼前一亮,确实和我见过的 PHP,Java,C#,JavaScript 实在不一样。我接触 Python 也有一段时间了,感觉还是有很多特性我是不熟悉的,确实有点感觉好奇 Python 还有多少类似这样的神奇特性?同样大家感觉哪些语言的特性哪些特性让你感觉眼前一亮的贴出来分享一下。
import pickle, StringIO
class Person(object):
# 自定义类型
def __init__(self, name, address):
self.name = name
self.address = address
def display(self):
print 'name:', self.name, 'address:', self.address
jj = Person("JGood", "中国 杭州")
jj.display()
file = StringIO.StringIO()
pickle.dump(jj, file, 0) # 序列化
print '+++++++++++++++++++++++++++++++'
print file.getvalue() #打印序列化后的结果
print '+++++++++++++++++++++++++++++++'
# del Person #反序列的时候,必须能找到对应类的定义。否则反序列化操作失败。
file.seek(0)
jj1 = pickle.load(file) # 反序列化 注意这里拿到的 jj1 相当于是 Person 实例了
# 见证奇迹的时刻
jj1.display()
file.close()
jj1 = pickle.load(file) # 反序列化
jj1.display()
1
sagaxu 2017-06-08 23:44:43 +08:00
Java 反序列化 JSON 得到的 object,不能调用它的方法吗?
|
3
GoBeyond 2017-06-08 23:53:30 +08:00 via Android
序列化别的语言没有么
|
4
wwqgtxx 2017-06-09 00:18:25 +08:00 via iPhone
如果反序列化得不到实例,那还要他有什么用
|
5
strahe 2017-06-09 00:19:22 +08:00
pickle 序列化对象,
python 中一切皆对象 |
6
ecloud 2017-06-09 00:20:41 +08:00
不是什么特别的东西
还不如 ZODB 来的爽 |
7
Kirscheis 2017-06-09 00:52:53 +08:00
我想这确实是你少见多怪了。。如果反序列化之后不是个实例,那你期待它是个什么呢。。
|
8
Miy4mori 2017-06-09 01:04:10 +08:00 via iPhone
厉害了厉害了
|
9
breeswish 2017-06-09 01:27:30 +08:00
像 C# 什么的也是可以反序列化出一个类的实例的呀
|
10
czheo 2017-06-09 02:57:30 +08:00
至少 Java 里面有类似的: https://www.tutorialspoint.com/java/java_serialization.htm
|
11
ericls 2017-06-09 06:34:17 +08:00 via iPhone
跨进程通信不是一直默认这个吗
|
12
est 2017-06-09 08:52:16 +08:00
|
14
zhchbin 2017-06-09 09:06:10 +08:00
歪个楼,python 的 pickle 模块还能用来留后门: https://blog.nelhage.com/2011/03/exploiting-pickle/
|
15
araraloren 2017-06-09 09:21:47 +08:00
~~ 我看完了才知道 说的是 序列化 反序列化
|
16
littleshy 2017-06-09 09:28:04 +08:00
序列化和反序列化跟语言没关系吧……
|
18
DietCola 2017-06-09 09:50:44 +08:00
令人窒息的 Python 秀
|
19
fwee 2017-06-09 10:05:48 +08:00
卧槽...水平是有多低
|
21
ipwx 2017-06-09 10:11:19 +08:00
Pickle 一般能避免就避免,有安全隐患。
|
22
ipwx 2017-06-09 10:21:39 +08:00 2
我觉得像 pickle 这种只能算小技巧,用它可以写程序,不用它也能写差不多程序。
Python 里面真正影响深远的特性,会真正影响整个程序的结构。首要的一个特性是 GIL,这导致了 CPython 写多线程就是渣渣,所以众多网络库走了 coroutine / multi-processing 的路子。coroutine 的代表是 gevent,multi-processing 可以算上各种 wsgi 容器,比如 uwsgi 和 gunicorn。 其二可以算上 Threading Local Storage,包括 Flask 的 request context,TensorFlow 的 default graph / session,等等。这是一个设计技巧,可以让你的程序在 coroutine 或者 multi-threading (有时候可以用,比如 TensorFlow 大量使用 C++ 绑定,在进入 C++ 程序段的时候会释放 GIL )的 context 下面,把一些全局变量当做单线程环境使用,是一种设计上的抽象。而且该特性对 gevent 之类的 coroutine 是透明的。 其三可以推 monkey patch。比如 gevent 可以对整个 Python 进程进行 monkey patch,使得所有 socket + threading 的多线程程序透明地转化为 socket + coroutine 的程序。 |
23
geew 2017-06-09 10:26:21 +08:00
是时候发一下这个了
In [7]: class A: ...: pass ...: In [8]: id(A()) == id(A()) Out[8]: True In [9]: print id(A()) 139817400142016 In [10]: print id(A()) 139817400142088 In [11]: def t(): ....: print id(A()) ....: print id(A()) ....: In [12]: t() 139817400142448 139817400142448 |
24
ipwx 2017-06-09 10:27:53 +08:00
最后一个,补充一条:其四是 Native Library 绑定。包括 Cython 的混合编译器,你可以写自己的 Native Code。或者现成的比如 NumPy。不要小看 Native Library 这一条,它会从根本上改变你写程序的思路。比如你原来习惯写 for 循环的,因为 Python 自身很慢要依赖 Native Library,你不得不把要做的操作搞成 batch operation,然后用 Native Library 一并执行。
比如用了 NumPy,你写一个分段函数 f(x) = x/2 (x^2==0) ; 3x+1 (x%2==1)。当 x 是一个大数组的时候,你会选择这么写: f = lambda x: ((x / 2) * (x%2 == 0) + (3*x + 1) * (x%2 == 1)) print(f(np.arange(N))) 因为 for 循环真的很慢,if 判断也很慢,所以哪怕你用 NumPy 把操作变成了 O(4N),也比用 Python 写一个裸的要快得多,当 N 很大的时候。 |
25
knightdf 2017-06-09 10:27:54 +08:00
好,威武,有希望了
不知道 LZ 见过的 PHP,Java,C#,JavaScript 是哪样的 |
26
felinx 2017-06-09 10:31:59 +08:00
你这个 display 改成 __str__ 来玩才是 Python 的神奇特性哦
|
27
xia0pia0 2017-06-09 11:04:06 +08:00
这是序列化的概念啊。。没啥神奇,php 也一样,java 也差不多。
|
28
jswh 2017-06-09 16:22:36 +08:00
Laravel 的 Job 就是用序列化和反序列化做的。
不过我不太喜欢这个东西,如果代码变动频繁,很容易出 bug。用的时候最好给要序列化的类价格 Version 字段。 |