Python 有多少类似这样的神奇特性 是我[Too Young Too Simple]少见多怪吗?

2017-06-08 23:39:53 +08:00
 dabpop139

前段时间学习一个 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()
5375 次点击
所在节点    Python
29 条回复
ipwx
2017-06-09 10:11:19 +08:00
Pickle 一般能避免就避免,有安全隐患。
ipwx
2017-06-09 10:21:39 +08:00
我觉得像 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 的程序。
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
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 很大的时候。
knightdf
2017-06-09 10:27:54 +08:00
好,威武,有希望了
不知道 LZ 见过的 PHP,Java,C#,JavaScript 是哪样的
felinx
2017-06-09 10:31:59 +08:00
你这个 display 改成 __str__ 来玩才是 Python 的神奇特性哦
xia0pia0
2017-06-09 11:04:06 +08:00
这是序列化的概念啊。。没啥神奇,php 也一样,java 也差不多。
jswh
2017-06-09 16:22:36 +08:00
Laravel 的 Job 就是用序列化和反序列化做的。
不过我不太喜欢这个东西,如果代码变动频繁,很容易出 bug。用的时候最好给要序列化的类价格 Version 字段。
mingyun
2017-06-10 09:22:30 +08:00
PHP 序列化对象私有属性没法获取到
@geew 这个神奇了,能否解释下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/367093

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX