草庐IT

python - 为什么 "import module"然后 "from package import module"再次加载模块?

coder 2023-08-15 原文

我的 PYTHONPATH 中有一个看起来像这样的包:

package/
    __init__.py
    module.py
        print 'Loading module'

如果我从 package/ 目录运行 Python(或在此目录中编写另一个模块)并键入

import module

它加载 module.py 并按预期打印出“加载模块”。但是,如果我接着输入

from package import module

它加载 module.py 并打印“加载模块”再次,这是我不期望的。这样做的理由是什么?

注意:我想我从技术上理解为什么 Python 这样做,因为 import module 的 sys.modules 键只是 "module",但对于 来自 package import module 它是 “package.module”。所以我想我想知道的是为什么这里的 key 不同——为什么不将文件的路径名用作 key ,以便 Python 在这里执行预期的操作?

最佳答案

实际上,通过从 package 目录运行代码,您错误地配置了 Python。您不应该将该目录放在 sys.path 上,因为它在包内。

Python 不使用文件名作为键,因为它不是导入文件,而是导入模块。允许人们执行“import c:\jim\my files\projects\code\stuff”会助长各种肮脏行为。

请考虑这种情况:如果您在 ~/foo/package/ 中,而 ~/barPYTHONPATH 中会怎么样 - 但是 ~/bar 只是 ~/foo 的符号链接(symbolic link)?您是否希望 Python 解析,然后为您删除重复的符号链接(symbolic link)?如果将相对目录放在 PYTHONPATH 上,然后更改目录会怎样?如果“foo.py”是“bar.py”的符号链接(symbolic link)怎么办?您是否希望这两个都被删除重复数据?如果它们不是符号链接(symbolic link),而只是精确的副本怎么办?添加复杂的规则以尝试在模棱两可的情况下做一些方便的事情意味着它会做一些对其他人来说非常不方便的事情。 (Python zen 12:面对歧义,拒绝猜测的诱惑。)

Python 在这里做了一些简单的事情,您有责任确保环境设置正确。现在,您可能会争辩说,默认情况下将当前目录放在 PYTHONPATH 上并不是一个好主意——我什至可能同意你的看法——但鉴于它在那里,它应该遵循相同的一致集其他路径条目执行的规则。如果它打算从任意目录运行,您的应用程序始终可以从 sys.path 中删除当前目录,方法是从 sys.path.remove('') 开始.

关于python - 为什么 "import module"然后 "from package import module"再次加载模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6282368/

有关python - 为什么 "import module"然后 "from package import module"再次加载模块?的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  4. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  5. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  6. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  7. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  8. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  9. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  10. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

随机推荐