我目前的理解(基于以下答案:一、二、三和Python文档)是如何在Python中导入的(以防万一:所有的代码片段都是在Python3.6.1上测试的)
假设我们有一个模块mod,它有子模块sub和sub1;sub反过来有一个函数func;那么我们可以(当然,考虑到安装在当前环境中的mod ):
import mod
mod.sub.func()
mod.sub1
# or
import mod.sub
mod.sub.func()
mod.sub1 # will result in "NameError: name 'mod' is not defined"
# or
from mod.sub import func
func()
mod.sub.func() # will result in "NameError: name 'mod' is not defined"
mod.sub1 # will result in "NameError: name 'mod' is not defined"最近,在Python中使用werkzeug.security.generate_password_hash和werkzeug.security.check_password_hash时,我注意到:
import werkzeug
werkzeug.security.generate_password_hash('some_password', method='pbkdf2:sha512', salt_length=25)AttributeError: module 'werkzeug' has no attribute 'security'检查结果。
尽管如此,下列功能仍然有效:
from werkzeug import security
security.generate_password_hash('some_password', method='pbkdf2:sha512', salt_length=25)当然,这也是:
import werkzeug.security
werkzeug.security.generate_password_hash('some_password', method='pbkdf2:sha512', salt_length=25)此外,还有:
from werkzeug.security import generate_password_hash
generate_password_hash('some_password', method='pbkdf2:sha512', salt_length=25)而且,有一点令人惊讶(至少对我来说),这个:
import werkzeug
from werkzeug import security
werkzeug.security.generate_password_hash('some_password', method='pbkdf2:sha512', salt_length=25)我的问题是:
import在Python中的工作方式,我的一些想法是错误的(或缺乏细节)吗?import werkzeug不允许我访问werkzeug.security?我的理解是-它应该导入werkzeug,以及它的所有子模块/属性。import werkzeug + from werkzeug import security允许访问werkzeug.security?我的理解是:它应该将绑定两个单独的名称(它们之间没有连接),如下所示:werkzeug到import werkzeug (即werkzeug模块)和security到from werkzeug import security (即werkzeug模块的security子模块)。发布于 2018-01-08 08:55:03
TL;DR:从werkzeug直接导入包含在字典中的任何属性,即from werkzeug import generate_password_hash。
在托马斯的回答的启发下,我将尝试总结我自己问题的答案:
import在Python中的工作方式,我的一些想法是错误的(或缺乏细节)吗?从我目前的立场来看,简短的回答是否定的。不过,最好记住,导入规则/机制可以通过__init__.py在包级别进行定制。
关于主题的进一步阅读:Python导入系统,官方importlib,导入Python模块文章。
import werkzeug不允许我访问werkzeug.security?我的理解是-它应该导入werkzeug,以及它的所有子模块/属性。正如托马斯·福桑格在他的回答:import werkzeug中正确指出的那样,import werkzeug没有从werkzeug模块导入security,因为将作为属性导入的唯一子模块是在__init__.py上定义的子模块(即exceptions和routing)。这一假设可由以下方面加以证实:
import werkzeug
werkzeug.routing # will return path to routing.py module
werkzeug.exceptions # will return path to exceptions.py module
werkzeug.security # AttributeError: module 'werkzeug' has no attribute 'security'import werkzeug + from werkzeug import security允许访问werkzeug.security?我的理解是:它应该将绑定两个单独的名称(它们之间没有连接),如下所示:werkzeug到import werkzeug (即werkzeug模块)和security到from werkzeug import security (即werkzeug模块的security子模块)。这是个棘手的问题。正如Werkzeug的__init__.py中所指出的,函数
展示我们想要展示的东西。
这可能是为什么:
import werkzeug
dir1 = dir(werkzeug)
werkzeug.security # AttributeError: module 'werkzeug' has no attribute 'security'
from werkzeug import security
dir2 = dir(werkzeug)
werkzeug.security # will return path to security.py module
# BUT!
dir1 == dir2 # True我想,托马斯也在这里,而且:
.
__getattr__()方法将返回显式导入的模块。
结论(或我学到的=):
如__init__.py所述
..。 Werkzeug提供的大多数函数和类都在HTTP和WSGI层上工作。这些程序没有有用的分组,这就是为什么它们都可以从" werkzeug“中导入,而不是在从文件中导入时替换延迟加载模块的implemented....The实现的模块。然后,对werkzeug模块的属性访问将延迟地从实现对象的模块中导入。
这意味着,而不是:
from werkzeug import security
security.generate_password_hash('some_password', method='pbkdf2:sha512', salt_length=25)
# OR
import werkzeug.security
werkzeug.security.generate_password_hash('some_password', method='pbkdf2:sha512', salt_length=25)
# OR
from werkzeug.security import generate_password_hash
generate_password_hash('some_password', method='pbkdf2:sha512', salt_length=25)
# OR
import werkzeug
from werkzeug import security
werkzeug.security.generate_password_hash('some_password', method='pbkdf2:sha512', salt_length=25)你可以简单地做:
from werkzeug import generate_password_hash
generate_password_hash('some_password', method='pbkdf2:sha512', salt_length=25)您可以以同样的方式导入和使用字典中包含的任何属性。
发布于 2020-02-04 08:51:58
如果您遵循这个语法,它就会正常工作。
import werkzeug as xyz这样,您还可以执行xyz.generate_hash_password()或调用xyz的任何其他函数。
https://stackoverflow.com/questions/47688957
复制相似问题