【发布时间】:2011-03-29 10:30:04
【问题描述】:
我最近经常使用math 模块。我不想一直写math.sqrt(x) 和math.sin(x)。我想缩短它并写成sqrt(x) 和sin(x)。
怎么样?
【问题讨论】:
我最近经常使用math 模块。我不想一直写math.sqrt(x) 和math.sin(x)。我想缩短它并写成sqrt(x) 和sin(x)。
怎么样?
【问题讨论】:
让我补充一点,我不仅认为from math import * 是命名空间污染的情况,而且还考虑from math import cos。这是因为当您在模块foo 上执行此操作时,然后您使用import foo; print( dir( foo ) ) 查看该模块的名称空间,您将在该列表中有一个项目cos。通常,这不是您想要的。
所以大多数时候我的所有导入看起来都像from math import cos as _cos,前导下划线是表示私人名称的常规标志。这个想法是从另一个模块导入和打印输出,import foo; print( name for name in dir( foo ) if not name.startswith( '_' ) ) 将为您提供在该模块中定义为公共的那些名称。
需要注意一件事:from math import cos as _cos; f = lambda x: _cos( x ) 在功能上与import math; g = lambda x: math.cos( x ) 并非 100% 相同。不同之处在于,在 python 中,名称解析发生在运行时,每次调用代码时。第一次导入时,名称cos 仅解析一次;对math 模块的任何后续更改都不会影响f()。通过第二次导入,每次调用cos 时都会针对math 进行解析,因此对数学模块的cos 方法的更改将传播到g()。当然,math 模块预计不会在运行时更改,在运行时更改模块的方法也不是特别值得推荐的编程技术。另一方面,模块只是一个对象,就像 python 中的其他所有内容一样,因此始终了解幕后发生的事情是值得的。
一般from math import cos as _cos; f = lambda x: _cos( x )就是你想要的,而且也比第二种形式快一点。
【讨论】:
你可以这样导入:
>>> from math import sqrt, sin
>>> sqrt(100)
10.0
发件人:More on modules
import 语句有一个变体,可以将模块中的名称直接导入到导入模块的符号表中。例如:
>>> from fibo import fib, fib2 >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377甚至还有一个变体可以导入模块定义的所有名称,这在交互式解释器中很有用:
>>> from fibo import * >>> fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377请注意,通常不赞成从模块或包中导入 * 的做法,因为它通常会导致代码可读性差。但是,可以使用它来节省交互式会话中的输入。
【讨论】:
对于较长的模块名称,通常会缩短它们,例如
import numpy as np
然后您可以使用短名称。或者您可以导入您需要的特定内容,如其他答案所示:
from math import sin, sqrt
这通常用于包内,用于更紧密耦合的代码。对于库,名称缩短的第一个选项通常是首选方式。
您应该永远不要使用from math import * 表单。它将污染名称空间,可能导致名称冲突并使调试更加困难。最重要的是,它使代码难以阅读,因为不清楚特定函数的来源。
可以在交互式解释器中产生异常。但是,一旦您习惯了使用缩写名称,可能就不值得在此处使用另一种约定。
【讨论】:
from math import sin, sqrt
# Then you can just do
sqrt(4)
【讨论】: