Python中有哪些类似这样的神奇特性,是我少见多怪吗?

前段时间学习一个 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()

Python中有哪些类似这样的神奇特性,是我少见多怪吗?

30 回复

Java 反序列化 JSON 得到的 object,不能调用它的方法吗?


我无法理解你的问题。

尴尬了,Java 没有玩多久,不能拿我的见识短误导了别人。

序列化别的语言没有么

如果反序列化得不到实例,那还要他有什么用

pickle 序列化对象,
python 中一切皆对象

不是什么特别的东西
还不如 ZODB 来的爽

我想这确实是你少见多怪了。。如果反序列化之后不是个实例,那你期待它是个什么呢。。

厉害了厉害了

像 C# 什么的也是可以反序列化出一个类的实例的呀

跨进程通信不是一直默认这个吗

你这算什么。10 年前我在学校 cpickle 了一个到 www.youtube.com 的 http 连接

10 年后我在 mac 上 unpickcle 了,居然还在继续收发数据!

pickle 不能序列化 socket 对象吧

歪个楼,python 的 pickle 模块还能用来留后门: https://blog.nelhage.com/2011/03/exploiting-pickle/

~~ 我看完了才知道 说的是 序列化 反序列化

序列化和反序列化跟语言没关系吧……

就是 http request 吧

令人窒息的 Python 秀

卧槽…水平是有多低

还有这种操作?

Pickle 一般能避免就避免,有安全隐患。

我觉得像 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 的程序。

是时候发一下这个了

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

最后一个,补充一条:其四是 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 很大的时候。

好,威武,有希望了
不知道 LZ 见过的 PHP,Java,C#,JavaScript 是哪样的

你这个 display 改成 str 来玩才是 Python 的神奇特性哦

这是序列化的概念啊。。没啥神奇,php 也一样,java 也差不多。

Laravel 的 Job 就是用序列化和反序列化做的。
不过我不太喜欢这个东西,如果代码变动频繁,很容易出 bug。用的时候最好给要序列化的类价格 Version 字段。

PHP 序列化对象私有属性没法获取到
这个神奇了,能否解释下

回到顶部