【问题标题】:Using a script to set variables in IDLE使用脚本在 IDLE 中设置变量
【发布时间】:2012-12-07 04:31:25
【问题描述】:

在 Win7 x64 上使用 Python 3.2。我有一个每次启动 IDLE 时都想运行的脚本。这是我的脚本:

import sys
from bs4 import BeautifulSoup

sys.setrecursionlimit(2000)

soup = BeautifulSoup()
def soupSetup(file_name, encode_type):
    soup = BeautifulSoup(open("C:\\Python32\\html\\"+file_name+".html", encoding=encode_type))

这样一切都设置好了,我所要做的就是传递soupSetup()我想使用的html文件,然后我就可以开始处理数据了。

我的问题是——如果我在使用print(soup.prettify())时按原样使用代码,我只会得到一个空行。如果我在运行 print 语句时不先实例化该类,我会得到:

Traceback (most recent call last):
  File "<pyshell#22>", line 1, in <module>
    print(soup.prettify())
NameError: name 'soup' is not defined

对于那些不熟悉 BeautifulSoup 汤的人来说,&lt;class 'bs4.BeautifulSoup'&gt; 是一个实例。

如何让汤对象在我的脚本之外持续存在?

【问题讨论】:

  • 两个问题合二为一。第一个关于要在启动时执行的代码的问题是通过根据docs.python.org/dev/library/site.html 在某个目录中创建模块 usercustomize/sitecustomize 来解决的。现在第二个问题可以通过在启动模块上增加__builtin__: import __builtin__; setattr(__builtin__, 'soup', soup) 来解决,然后soup 将神奇地在其他任何地方可用。我不建议这样做,您可能需要重新考虑您想要实现的目标。此外,在您的正确方法中,您需要重新定义全局 soup
  • 你应该把它作为答案......因为它完全回答了他的问题......

标签: python python-3.x beautifulsoup python-idle


【解决方案1】:

您使用声明 soup = BeautifulSoup() 创建模块的全局名称 soup。然后,在函数soupSetup 中,您希望将soup 名称重新分配给另一个BeautifulSoup() 对象,这次是数据。

但是:函数内部的名称是该函数的本地名称,并且不会保留在该函数之外。因此,您最终不会重新分配全局 soup 名称,而是在函数内部创建一个新的单独的 soup 变量,然后在函数存在时将其删除。全局 soup 没有被更改。这就是为什么您在使用 soup 变量时会获得首先创建的空的 BeatifulSoup() 对象。

您需要做的是告诉函数您要重新分配全局名称,如下所示:

def soupSetup(file_name, encode_type):
    global soup
    soup = BeautifulSoup(open("C:\\Python32\\html\\"+file_name+".html", encoding=encode_type))

应该这样做。 此外,您不必设置soup = BeautifulSoup(),您将其设置为什么都没有关系,因为它将被函数覆盖。只需这样做:

soup = None

完整的代码最终应该是:

import sys
from bs4 import BeautifulSoup

sys.setrecursionlimit(2000)

soup = None
def soupSetup(file_name, encode_type):
    global soup
    soup = BeautifulSoup(open("C:\\Python32\\html\\"+file_name+".html", encoding=encode_type))

【讨论】:

  • 这真的没有抓住重点。他得到了一个NameError 异常。
  • @mmgp:如果他没有如他所说的“首先实例化类”,即如果跳过模块级别的soup = BeautifulSoup() 语句,他只会得到 NameError 异常。即使在重新阅读之后,我也很有信心我没有错过任何分数。
  • 老实说,我认为您误解了他的尝试。他有一些代码应该在他启动 IDLE 时运行。现在代码已经运行,他尝试使用名称soup,但找不到它,因为它仅在已经运行的代码中定义。
  • @mmgp:不,这不是他写的。你没有仔细阅读这个问题。他明确指出“如果我在使用 print(soup.prettify()) 时按原样使用代码,我只会得到一个空行”。他可以访问soup,但他用空的 BeautifulSoup() 对象来实例化全局对象。
  • 请参阅:“如何让汤对象在我的脚本之外持续存在?”
【解决方案2】:

两个问题合二为一。

关于启动时要执行的代码的第一个问题是通过根据http://docs.python.org/dev/library/site.html在某个目录中创建模块 usercustomize/sitecustomize 来解决的。

现在第二个问题可以通过扩充__builtin__来解决:

import __builtin__
setattr(__builtin__, 'soup', soup)

在启动模块上(在适当的位置),然后汤将神奇地在其他任何地方可用。我不建议这样做,您可能需要重新考虑您想要实现的目标。此外,在您当前的方法中,您在 soupSetup 中重新定义了 soup。因此,在该函数中,您需要指定您正在重新定义全局变量而不是创建局部变量:

def soupSetup(...):
    global soup
    ...

【讨论】:

  • 这个可怕的 hack 可能会解决问题,但在这种情况下它不是正确的解决方案,因为他的问题是他希望在函数中更新全局变量,但它不会这样做。
  • 想解释一下这个答案如何不处理全局变量的更新?这个问题间接询问了这个hack,因为他想进一步导出全局soup
  • 他已经可以访问全球soup。 “如果我在使用 print(soup.prettify()) 时按原样使用代码,我只会得到一个空行。”您需要仔细阅读问题。
  • 如果他说他想在给定函数之外坚持soup,我对此毫无疑问,因为那样就完全不同了。
  • 好吧,你是新来的,所以我来解释一下:当一个Python新手进来并解释他想做什么时,他经常是错的,因为他是一个新手并且误解了一些东西或者使用了错误的术语。这里就是这种情况。根据他对错误的描述,完全清楚soup 确实“存在于脚本之外”。因此,当他说他希望soup 在脚本之外持续存在时,他误解了正在发生的事情。既然你听了他的错误分析,你也听了。另一方面,仔细阅读他的问题。你应该这样做。
猜你喜欢
  • 1970-01-01
  • 2021-04-02
  • 2023-01-09
  • 1970-01-01
  • 2015-04-30
  • 1970-01-01
  • 1970-01-01
  • 2019-03-16
  • 2022-09-24
相关资源
最近更新 更多