python 常见问题

Created On: 2016-10-19

python中文答疑QQ群

本文会持续更新,但是也只是包含常见问题,如果有更多疑问,欢迎加入python学习答疑QQ群,群号:477379859。点击链接加入群【python学习答疑群】

python安装

  • 我应该选择 python 2 还是 python 3?

    如果你需要问这个问题,通常你应该选择 python 3。如果有更复杂的场景需要做针对性分析,可以邮件我。

  • 我应该安装哪个 python 版本?

    如果没有特殊需要,建议安装python官网的版本。其它常见的版本包括用于科学计算的anaconda,运行速度更快、支持JIT的pypy

  • 我可以同时安装python2和python3吗?

    是的。只要安装在不同的目录就可以了。使用的时候可以用python2或者python3命令,也可以创建对应环境的virtualenv

    事实上,你可以同时安装多个python 2和python 3的版本。它们都可以共存。只要用 python3.5 这样的命令启动就可以了。

  • 我应该用哪个IDE?

    你可以尝试 JetBrain 的 PyCharm 或者 Microsoft 的 Python Tools for Visual Studio。另外程序员常见的编辑器 (Emacs, Vim, Sublime Text, VS code, Atom 等) 都有python相关的插件。

python3

  • Python 2 和 Python 3 有哪些主要区别?
    • 字符串类型变化。
    • 部分标准库的函数位置或者行为有小改动。
    • 很多标准库的模块被重命名。
    • 标准库新增了一些模块。
    • yield from语法。
    • async/await语法。
    • print函数。

    更详细的差别,请参考官方文档

  • 同时装了Python3和Python2,怎么用pip?

    pip/pip2对应python2,pip3对应python3。其它子命令、参数和原来一样。如果使用了virtualenv, python3 也可以直接用 pip。

  • reload函数不见了?

    reload 函数在 python3 里面被移动到 importlib 模块下了。

    import importlib
    importlib.reload
    

学习资料

  • 有什么推荐的入门学习资料吗?

    python是一个用户友好的语言,入门可以看官方的 tutorial这里有中文翻译。不需要看已经很旧的出版的书。通常那些书并不值得。

    tutorial 结束后,可以开始熟悉标准库

安装软件包

  • 我应该怎样安装软件包?

    使用 Google 或者 pypi搜索 查找软件包的名称,然后使用 pip 安装。不要手动下载tar.gz包,不要自己运行python setup.py命令,不要使用easy_install。

    对于不在 pypi 上的软件包,可以使用pip直接从git源或tar.gz URL安装

    如果你使用 anaconda 发行版,可以使用 conda 命令安装该发行版专属的软件包。

  • pip安装总是失败或者卡住,怎么办?

    如果pip install命令无响应或者下载失败,可能是墙的原因,建议使用墙内的PyPI镜像,比如清华的开源镜像。

    如果安装失败,通常是 python-dev, C编译器或者python包所依赖的软件包没有安装。需要具体问题具体分析。

  • 如何使用国内的PyPI镜像,加速pip软件包安装过程?

    常见使用镜像的方法有两种,第一种是直接pip install命令带参数,第二种是把镜像配置写到pip配置文件。

    命令行带参数:

    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple <pkg>
    

    写配置文件,创建 ~/.pip/pip.conf,内容如下:

    [global]
    index-url = https://pypi.tuna.tsinghua.edu.cn/simple
    

    豆瓣PyPI镜像不支持HTTPS,目前不推荐使用。

语法和内置函数

  • 为什么python函数返回值总是None?

    python并不会把函数的最后一个值作为返回值,你需要明确使用 return 语句。如果没有用return语句,函数默认返回None。

    这和 common lisp, ruby 等语言是不同的。

  • 怎样将整数转成字符串?怎样将字符串转成整数?
    assert str(100) == "100"
    assert int("100") == 100
    
  • 无限循环该怎么写?
    while True:
        xxx
    
  • python怎么把字符串最后一个字符去掉?
    s = s[:-1]
    
  • python list之append和extend的区别?

    append 的参数是单个元素搜索,extend的参数是一组元素(iterable)。

  • python 支持运算符重载吗?

    支持。见官方文档 special-method-namesemulating-numeric-types. 简单地说,想要重载+运算符,你需要在自己的类里面定义__add__()和__radd__()方法。

  • 正则表达式里面如果有中文或者非ASCII字符,该怎么表示?

    在python2里面,需要使用u前缀标示unicode字符串,比如ur'中文[a-z]'或者使用 from __future__ import unicode_literals. python3无须特殊对待。

  • 怎样使 Python 输出时不换行?

    python2, print语句后面多加一个逗号,例如

    print 1,
    

    python3, print函数使用end参数,例如

    print(1, end='')
    

    python2里面也可以使用print函数,但是需要先做这个import搜索:

    from __future__ import print_function
    
  • a = b = 0 是什么意思?a, b = b, a + b 又是什么意思?
    • a = b = 0 表示 a, b 都赋值为 0. 类似的表达还有 a < x < b,和数学上的意思一样。在python里面,这种东西不需要拆分成两个表达式。
    • a, b = b, a + b 是并行赋值,表示同时执行 a = b, b = a + b,执行b的赋值的时候,a还是旧值。这种形式可以扩展成将任意多个值,赋值给任意多个变量。在 lisp 里面一般叫 destructuring bind.

常见模块和包

  • 做json解析我该用哪个包?

    标准库内置的json模块已经很快,建议使用该模块。

  • json date, datetime 对象无法 encode?

    是的。默认情况下 date, datetime 都无法直接 encode. 你可以在stackoverflow上找到更多类似的问题。通常,我会用自己封装的to_json函数:

    import datetime
    import json
    
    
    class BetterJsonEncoder(json.JSONEncoder):
        """why python's built-in json encoder doesn't support date/datetime?
    
        This is a replacement that support those data types.
    
        """
        def default(self, obj):    # pylint: disable=method-hidden
            if isinstance(obj, datetime.date):
                return obj.isoformat()
            if isinstance(obj, datetime.datetime):
                return obj.isoformat()
            return json.JSONEncoder.default(self, obj)
    
    
    def to_json(obj, cls=BetterJsonEncoder, **kwargs):
        """convert python object to json string.
    
        This function supports date and datetime objects.
        If you have custom class, try subclass BetterJsonEncoder and use
        json.dumps(obj, cls=YourJsonEncoder) instead.
    
        Args:
            obj: any python object
            cls, **kwargs: the same kwargs accepted by json.dumps()
    
        Return:
            a string in json format. This may raise TypeError if object is not
            JSON serializable
    
        """
        return json.dumps(obj, cls=cls, **kwargs)
    
  • logging 为什么什么都不输出?

    logging 模块的配置是比较复杂的。建议详读官方文档。如果在一个简单的命令行程序 里面使用:

    from __future__ import unicode_literals
    
    import logging
    logging.basicConfig(format='%(levelname)-8s %(message)s',
                        level=logging.INFO)
    logger = logging.getLogger('')
    
    logger.info("some info msg")
    logger.error("some error")
    

简单算法

简单算法通常可以在 Google 或者 rosetta code 中找到。Learn X in Y Minutes也可以作为快速参考。

  • 如何把嵌套的python list转成一个一维的python list?
    from itertools import chain
    
    def flatten(list_of_lists):
        "Flatten one level of nesting"
        return list(chain.from_iterable(list_of_lists))
    
    print(flatten([[1,2,3], [4,5]]))
    # output is [1, 2, 3, 4, 5]
    
  • 为什么python标准库没有内置时区?怎样获取指定时区的地方时?

    时区是一个经常更新的东西,所以没有放在标准库。pytz 内置了世界上大部分时区。

    >>> import pytz
    >>> import datetime
    >>> datetime.datetime.now(pytz.timezone('Asia/Shanghai'))
    datetime.datetime(2016, 8, 5, 17, 13, 52, 893693, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)
    >>>
    
  • python读取文件,如何去掉每一行末尾的换行符"\n"?
    with open(filename, 'r') as f:
        for line in f:
            line = line[:-1]
            # your code here
    

编写命令行程序

  • 双击py文件执行时,弹出个窗口就马上消失了,怎么办?

    命令行程序运行完都是自动关闭的。那些年中国学生被VC6洗脑了,都以为程序写了就自动支持按任意键关闭窗口。其实除了学习的时候,其它时候没有任何程序适合让IDE自动加“按任意键继续”这种功能的。这种功能会让程序的通用性变差很多,因为很难在其它程序里面调用,或者使用管道串联几个命令。所以除了学习的时候,其它时候不要乱加这种功能。另外,好一点的IDE在运行时都会在IDE里面自动显示运行结果,也不需要加这些东西。

    怎么解决?自己在 module 或者 main() 末尾加上这个功能:

    print("hello world")    # this is your code
    i = input("Press Enter key to continue...")    # add this line
    
  • python 怎么启动一个外部命令程序,并且不阻塞当前进程?
    import subprocess
    
    subprocess.Popen(["sleep", "30"])    # this is non-blocking.
    

    python退出之后,sleep依然在后台执行。

  • 如何执行一个外部命令,并获取输出?
    from __future__ import print_function, unicode_literals
    
    import subprocess
    
    
    def main():
        python_version = subprocess.check_output(["python", "--version"])
        print(python_version.decode("utf-8"))    # your console's encoding
    
    
    if __name__ == '__main__':
        main()
    

多线程和并发编程

  • 我听说过GIL,到底什么是GIL?python能用到所有的CPU核吗?

    你可以自己 Google 这个问题查找详细答案。我只想说,对于 CPU 密集型的任务,python并不适合。对于 IO 密集型任务,python可以胜任。

  • 到底什么是异步IO?什么是协程?我该用哪个库解决我的问题?

    异步IO是指在一个程序中,涉及到IO的部分,都是非阻塞的,这样可以充分利用CPU资源在等待IO的时候做别的事情。

    协程是一种多线程的编程模型。它是一种轻量级线程,编写的时候看起来是多线程方式,实际执行的时候是合作式、单线程方式。使用协程的程序,只要有一处阻塞,所有协程都会被阻塞。

    常见的异步IO框架有 tornado (web), gevent (network, system), twisted (network), asyncio (network, system). 这些框架都有自己的协程实现方式,有的可以共用,有的不行。

    该用什么框架,还是要具体问题,具体分析。没有一个库能解决所有问题。

数据库和存储

字符串和编码问题

  • 我看到有的字符串前面有u"",这是什么?

    这是 python 2 里面的unicode字符串。在 python 2 里面,默认不带u的字符串是byte数组(str类型),带u的字符串是unicode字符串(unicode类型) 。

    在python3.4+里面,不管带不带u,默认字符串都是unicode字符串(python3的str类型)。

  • 我看到乱码!我的程序抛了 UnicodeDecodeError 异常!

    这是一个很常见,也很复杂的问题,需要一篇文章单独解释。目前这篇文章还没有完成。有具体相关的问题请加群提问。

爬虫

  • 用Python写爬虫,用什么框架比较好?

    scrapy是专业的python爬虫框架,文档、执行效率都OK。如果想完全自己写,建议使用支持异步IO的库和框架,常见的包括 gevent, asyncio, twisted.

此信息是否有帮助?