从 werkzeug 导入安全导入 werkzeug VS

2024-02-13

我目前的理解(基于这些答案:one https://stackoverflow.com/questions/9439480/from-import-vs-import, two https://stackoverflow.com/questions/710551/import-module-or-from-module-import, ; and Python 文档 https://docs.python.org/3/reference/import.html#submodules) Python 中导入的工作原理是(以防万一:所有代码片段均在 Python 3.6.1 上测试):

假设我们有一个模块mod,它有子模块sub and 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"

最近在玩的时候werkzeug.security.generate_password_hash and werkzeug.security.check_password_hash,在Python控制台中,我注意到:

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)

我的问题是:

  1. 我的一些想法是否错误(或缺乏细节),关于如何import在 Python 中工作吗?
  2. Why import werkzeug不会让我访问werkzeug.security?我的理解是——它应该导入werkzeug,以及它的所有子模块/属性。
  3. Why import werkzeug + from werkzeug import security允许访问werkzeug.security?我的理解:它应该绑定两个不同的名字(它们之间没有联系), 如下:werkzeug to import werkzeug (i.e. werkzeug模块)和security to from werkzeug import security (i.e. security的子模块werkzeug module.

我不确定我能否很好地回答您的所有问题,但我发现它很有趣并看了一下,这是我的结果。

一般来说,import mod.sub or from mod import sub假设sub是一个子模块mod包裹。然而,这也可能意味着sub是在 a 中声明的字段/变量mod module.

存在一个__init.py__-file 将表示 https://docs.python.org/3/tutorial/modules.html#packages文件夹是一个包:

需要 __init__.py 文件才能使 Python 将目录视为包含包;这样做是为了防止具有通用名称(例如字符串)的目录无意中隐藏稍后出现在模块搜索路径上的有效模块。在最简单的情况下,__init__.py 可以只是一个空文件,但它也可以执行包的初始化代码(...)。

我相信,from werkzeug import security and import werkzeug.security两者都导入一个模块security, thus security.generate_password_hash是已知且有效的属性。基本上,from werkzeug.security import generate_password_hash通过有效的导入语句直接导入该属性。

In the Werkzeug 快速入门 http://werkzeug.pocoo.org/docs/0.13/quickstart/文档中,我发现了以下内容:

确保从文档建议的位置导入所有对象。理论上,在某些情况下可以从不同位置导入对象,但这不受支持。

此外,Werkzeug过渡到 1.0 http://werkzeug.pocoo.org/docs/0.13/transition/ states:

Werkzeug 最初有一个神奇的导入系统钩子,可以从一个模块导入所有内容,并且仍然根据需要延迟加载实际的实现。不幸的是,事实证明这很慢,而且在替代 Python 实现和 Google 的 App Engine 上也不可靠。

从 0.7 开始,我们建议不要进行短期导入,并强烈鼓励从实际实现模块开始导入。 Werkzeug 1.0 将完全禁用神奇的导入钩子。

看起来Werkzeug 修改 https://github.com/pallets/werkzeug/blob/master/werkzeug/__init__.py如何加载模块。 (我推测,这在具有贡献内容的大型包中并不罕见,例如 Flask、Django;其动机是延迟加载、提高性能或管理跨包传播的贡献模块内容。)

正如你所发现的,import werkzeug does not import security来自werkzeug模块,因为(据我所知),only将作为属性导入的子模块是定义在line 100 https://github.com/pallets/werkzeug/blob/master/werkzeug/__init__.py#L100__init__.py 的:

# modules that should be imported when accessed as attributes of werkzeug
attribute_modules = frozenset(['exceptions', 'routing'])

在同一个文件中,当看着 https://github.com/pallets/werkzeug/blob/master/werkzeug/__init__.py#L110韦克泽格的module(ModuleType)- 类及其__getattr__()-method:

class module(ModuleType):

    """Automatically import objects from the modules."""

    def __getattr__(self, name):
        if name in object_origins:
            module = __import__(object_origins[name], None, None, [name])
            for extra_name in all_by_module[module.__name__]:
                setattr(self, extra_name, getattr(module, extra_name))
            return getattr(module, name)
        elif name in attribute_modules:
            __import__('werkzeug.' + name)
        return ModuleType.__getattribute__(self, name)

看来模块名称在object_origins字典,通过定义all_by_module,必须单独导入,并且werkzeug.security is 其中之一 https://github.com/pallets/werkzeug/blob/master/werkzeug/__init__.py#L95.

最后,我认为原因是:

import werkzeug     
from werkzeug import security  

组合有效,第一行就是这样not进口安全,但第二个does,和__getattr__()-method 将返回显式导入的模块。

Edit: 最后一部分不正确,经过测试Filipp https://stackoverflow.com/users/8554766/filipp-w:

我希望通过简单地做from werkzeug import security那仍然werkzeug.security.generate_password_hash()会工作。 (我还没有测试或证实这一点)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 werkzeug 导入安全导入 werkzeug VS 的相关文章

随机推荐

  • ActiveAdmin:批量选择所有页面

    使用 activeadmin 是否可以对特定模型的所有记录执行批处理操作 而不是仅在当前页面上选择的记录 默认批处理操作仅对当前页面中的选择进行操作 您必须定义自己的批处理操作 该操作仅忽略选择并对所有记录执行操作 See http act
  • 为什么在检查依赖关系时使用 GemSpec + GemFile?

    每当开发 gems 时 我看不出有任何理由不直接检查 Gemfile 的依赖关系 确实 为什么要使用 gemspec文件以便列出它们 有真正的好处吗 嗯 那是因为Gemfile不是来自 Rubygems 的文件 而是来自 Bundler 的
  • 制作一个独立的列表(?)

    我正在尝试列表并尝试显示以下代码段 hello 但要做到这一点 我需要让 3 个 listSmall 彼此独立 有没有办法做到这一点 当前输出当然是 hello hello hello listSmall listBig listSmall
  • 在保存付款方式之前如何获取报价总额?

    我正在尝试创建一步结帐 但在结帐页面中我遇到了订单审核部分的问题 当我选择付款方式时 例如 货到付款 有 5 美元的额外费用 或者 checkorder 有 4 的折扣 或者 信用卡付款 会在订单总额中增加额外费用 我需要一种在保存付款方式
  • 将 AnyGenerator 与 Swift 2.2+ 一起使用(自定义类的“for in”循环支持)

    以前我使用以下函数使我的自定义类符合 SequenceType 协议 func generate gt AnyGenerator
  • 我想从 MySQL 数据库中随机选择一个 YouTube 视频,并将其显示在我的网页上 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我有一个名为 Videos 的 My
  • Bootstrap 4 导航栏将徽标中心对齐并在左侧切换图标

    我想让徽标居中 链接位于导航栏的左侧 当它们在小型设备中折叠时 切换按钮应出现在左侧 此处出现在右侧 并且徽标应固定 不折叠
  • JNI 对象指针

    Problem 在尝试 JNI 接口时 我想知道是否可以采取JObject并将其转换为等效的结构来操作字段 然而 当我尝试时 我惊讶地发现这不起作用 忽略这个想法可能有多么可怕 为什么它不起作用呢 我的方法 Java测试类 我做了一个简单的
  • 向 ggplot2 添加小刻度和标签

    必须有一种更简单的方法来使用 ggplot2 在图中添加自定义刻度和标签 而不是像论坛中的一些答案那样创建自定义函数 这是我的代码 data lt data frame WS Spd WVT c 0 5 1 2 4 2 0 3 C E c
  • python如何比较字符串和整数[重复]

    这个问题在这里已经有答案了 在下面的代码中 这是一个用于对元素进行排序的简单算法 我的问题是如何在内部比较字符串以及解释器如何知道这些字符串将放置在整数之后 a 22 66 54 11 16 2 5 b a 3 2 1 gt gt gt f
  • 如何在kafka中初始化kafka ConsumerRecords进行测试

    我正在为 kafka 消费者组件和模拟编写测试用例kafkaConsumer poll 它返回的实例ConsumerRecords
  • 设置 md-grid-list 样式

    我正在使用 Angular Material 网格列表来显示大约 500 1000 个项目 我在根据自己的喜好设计它时遇到了一些麻烦 这是网格列表现在的样子
  • Cassandra中删除表或截断表哪个更好

    我们有一个用例 我们需要每天使用 Cassandra 中的当前数据重新创建一个表 为此 我们应该使用 drop table 还是 truncate table 哪个会更有效率 我们不希望数据被备份等 谢谢 安库尔 我认为对于几乎所有情况 截
  • Windows 8 Phone 客户端证书 HTTPS 身份验证

    我正在尝试使用我正在开发的 Windows 8 Phone 应用程序中的客户端证书访问安全的 HTTPS 服务器 这根本不起作用 这让我尝试从标准 Web 浏览器访问 HTTPS 服务器 但它也不起作用 我不知道 Internet Expl
  • 从 SonarQube 删除项目

    有谁知道如何从 SonarQube 服务器删除项目 谢谢 罗南 您有 2 种方法可以删除项目 如果您是项目的管理员 则可以从其配置操作中将其删除 gt 参见 项目管理 文档页面中的 删除项目 https docs sonarqube org
  • 如何从 SQL Server 中的 TOP 中排除 LEFT JOINed 表?

    假设我有两个书籍表和两个对应版本的表 我有一个查询如下 SELECT TOP 10 FROM SELECT hbID hbTitle hbPublisherID hbPublishDate hbedID hbedDate FROM hard
  • Typescript 和 React 组件接受 TextArea 和 Input 的 onChange

    我是打字稿新手 我正在尝试创建一个输入组件 如果它收到type text 它呈现一个input如果它收到type textarea 它呈现 你明白了 一个textarea 问题是 当我在代码中使用该组件时 打字稿会抱怨onChange 似乎
  • 与我的自定义 Streambuf 类一起使用时,istream::tellg() 返回 -1?

    我正在尝试创建一个istream直接从原始内存缓冲区读取 我在这里的另一篇文章中找到了一个很好的方法 class membuf public basic streambuf
  • 在 C 中编码多管道

    我正在尝试在 C 中为我的 shell 实现多管道 我所拥有的只是一个管道函数 用于管道 b 但不是 a 乙 C int c 2 int returnv pid t id pipe c pid fork 0 if pid dup2 c 1
  • 从 werkzeug 导入安全导入 werkzeug VS

    我目前的理解 基于这些答案 one https stackoverflow com questions 9439480 from import vs import two https stackoverflow com questions