V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
dabpop139
V2EX  ›  Python

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

  •  
  •   dabpop139 · 2017-06-08 23:39:53 +08:00 · 5376 次点击
    这是一个创建于 2760 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前段时间学习一个 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 条附言  ·  2017-06-09 01:10:42 +08:00
    刚才测试了一下 PHP 也可以这样玩,平常我常用的也只是序例化一些数组和 JSON 啥的,没想到还可以序列化实例,涨姿势了。看来要学的还很多。
    第 2 条附言  ·  2017-06-09 12:48:31 +08:00
    感谢大家用心的回复,序例化和反序列化我平常用在一些基础数据类型(数组和 JSON 等)操作多一点,序例化和反序列化一个实例的操作一般适合用在哪些场景呢?还有就是魔术方法这块,感觉 Python 的魔术方法还是蛮多的,魔术方法把控不好应该很容易造成混乱。
      另外我想学习应该还是要谦虚,不懂就是不懂,总比不懂装懂强。引用昨天看到的一句话,分享给大家 “人生在世,首先是做人,其次,是做社会人,再次是做职业人,末次,才是专业人”。
    29 条回复    2017-06-10 09:22:30 +08:00
    sagaxu
        1
    sagaxu  
       2017-06-08 23:44:43 +08:00
    Java 反序列化 JSON 得到的 object,不能调用它的方法吗?
    dabpop139
        2
    dabpop139  
    OP
       2017-06-08 23:52:33 +08:00
    @sagaxu 尴尬了,Java 没有玩多久,不能拿我的见识短误导了别人。
    GoBeyond
        3
    GoBeyond  
       2017-06-08 23:53:30 +08:00 via Android
    序列化别的语言没有么
    wwqgtxx
        4
    wwqgtxx  
       2017-06-09 00:18:25 +08:00 via iPhone
    如果反序列化得不到实例,那还要他有什么用
    strahe
        5
    strahe  
       2017-06-09 00:19:22 +08:00
    pickle 序列化对象,
    python 中一切皆对象
    ecloud
        6
    ecloud  
       2017-06-09 00:20:41 +08:00
    不是什么特别的东西
    还不如 ZODB 来的爽
    Kirscheis
        7
    Kirscheis  
       2017-06-09 00:52:53 +08:00
    我想这确实是你少见多怪了。。如果反序列化之后不是个实例,那你期待它是个什么呢。。
    Miy4mori
        8
    Miy4mori  
       2017-06-09 01:04:10 +08:00 via iPhone
    厉害了厉害了
    breeswish
        9
    breeswish  
       2017-06-09 01:27:30 +08:00
    像 C# 什么的也是可以反序列化出一个类的实例的呀
    czheo
        10
    czheo  
       2017-06-09 02:57:30 +08:00
    ericls
        11
    ericls  
       2017-06-09 06:34:17 +08:00 via iPhone
    跨进程通信不是一直默认这个吗
    est
        12
    est  
       2017-06-09 08:52:16 +08:00
    你这算什么。10 年前我在学校 cpickle 了一个到 www.youtube.com 的 http 连接

    10 年后我在 mac 上 unpickcle 了,居然还在继续收发数据!
    wwqgtxx
        13
    wwqgtxx  
       2017-06-09 08:54:34 +08:00 via iPhone
    @est pickle 不能序列化 socket 对象吧
    zhchbin
        14
    zhchbin  
       2017-06-09 09:06:10 +08:00
    歪个楼,python 的 pickle 模块还能用来留后门: https://blog.nelhage.com/2011/03/exploiting-pickle/
    araraloren
        15
    araraloren  
       2017-06-09 09:21:47 +08:00
    ~~ 我看完了才知道 说的是 序列化 反序列化
    littleshy
        16
    littleshy  
       2017-06-09 09:28:04 +08:00
    序列化和反序列化跟语言没关系吧……
    laoyuan
        17
    laoyuan  
       2017-06-09 09:42:04 +08:00
    @wwqgtxx 就是 http request 吧
    DietCola
        18
    DietCola  
       2017-06-09 09:50:44 +08:00
    令人窒息的 Python 秀
    fwee
        19
    fwee  
       2017-06-09 10:05:48 +08:00
    卧槽...水平是有多低
    Kilerd
        20
    Kilerd  
       2017-06-09 10:11:12 +08:00 via iPhone
    @est 还有这种操作?
    ipwx
        21
    ipwx  
       2017-06-09 10:11:19 +08:00
    Pickle 一般能避免就避免,有安全隐患。
    ipwx
        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 的程序。
    geew
        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
    ipwx
        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 很大的时候。
    knightdf
        25
    knightdf  
       2017-06-09 10:27:54 +08:00
    好,威武,有希望了
    不知道 LZ 见过的 PHP,Java,C#,JavaScript 是哪样的
    felinx
        26
    felinx  
       2017-06-09 10:31:59 +08:00
    你这个 display 改成 __str__ 来玩才是 Python 的神奇特性哦
    xia0pia0
        27
    xia0pia0  
       2017-06-09 11:04:06 +08:00
    这是序列化的概念啊。。没啥神奇,php 也一样,java 也差不多。
    jswh
        28
    jswh  
       2017-06-09 16:22:36 +08:00
    Laravel 的 Job 就是用序列化和反序列化做的。
    不过我不太喜欢这个东西,如果代码变动频繁,很容易出 bug。用的时候最好给要序列化的类价格 Version 字段。
    mingyun
        29
    mingyun  
       2017-06-10 09:22:30 +08:00
    PHP 序列化对象私有属性没法获取到
    @geew 这个神奇了,能否解释下
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1869 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 16:16 · PVG 00:16 · LAX 08:16 · JFK 11:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.