【问题标题】:global name 'doc' is not defined, trouble withvcall from one function to annother未定义全局名称“doc”,从一个函数调用另一个函数时出现问题
【发布时间】:2013-11-07 14:03:50
【问题描述】:

我目前正在编写的一段代码遇到了一些问题。

使用以下代码,我得到 NameError: global name 'doc' is not defined。

def createHtml():
    name = input("\nEnter the name for your HTML-page: ")   
    doc = open(name + ".html", 'w')

def createTitle():
    print (t[0], file=doc) #<!DOCTYPE html>
    print (t[1], file=doc) #<html>
    print (t[2], file=doc) #<head>
    title = input("Enter your title here: ")
    print ("  <title>",title,"</title>", file=doc)
    print (t[3], file=doc) #</head>

我知道这是因为文档仅在 createHtml 函数中定义。但是,如果我想让同一个文档在不同的函数中调用时工作,我该如何让它工作呢?我不能将它排除在 createHtml 函数之外,因为它会弄乱我的程序,因为我有一个允许用户从不同功能中进行选择的菜单。 像这样:

while True:
    menu = input("\nPress 1 to enter the file name for the HTML-page"
                 "\nPress 2 to enter title for the HTML-page"
                 "\nPress 3 to start entering code in body"
                 "\nPress 4 to exit\n")
    if menu == "1":
        createHtml()
    elif menu == "2":
        createTitle()
    elif menu == "3":
        createBody()
    else:
        print ("Good bye!")
        break
doc.close()

并且文档由name变量定义在:

name = input("\nEnter the name for your HTML-page: ")

有没有办法从 createHtml-function 获取 doc 到我的其他函数?

【问题讨论】:

  • 在while 循环之前创建doc。将其传递给每个函数。

标签: python function python-3.x defined


【解决方案1】:

将函数包装在一个类中怎么样?

class HtmlBuilder(object):

    def __init__(self):
        self.doc = None

    def createHtml(self):
        name = input("\nEnter the name for your HTML-page: ")   
        self.doc = open(name + ".html", 'w')

    def createTitle(self):
        print (t[0], file=self.doc) #<!DOCTYPE html>
        print (t[1], file=self.doc) #<html>
        print (t[2], file=self.doc) #<head>
        title = input("Enter your title here: ")
        print ("  <title>",title,"</title>", file=doc)
        print (t[3], file=self.doc) #</head>

    def Dispose(self):
        self.doc.flush()
        self.doc.close()

然后像这样使用它:

hb = HtmlBuilder()
while True:
    menu = input("\nPress 1 to enter the file name for the HTML-page"
                 "\nPress 2 to enter title for the HTML-page"
                 "\nPress 3 to start entering code in body"
                 "\nPress 4 to exit\n")
    if menu == "1":
        hb.createHtml()
    elif menu == "2":
        hb.createTitle()
    elif menu == "3":
        hb.createBody()
    else:
        print ("Good bye!")
        break

hb.Dispose()

归根结底,这是面向对象编程的完美用例,不是吗?在此之后,可以进行很多良好的改进。

例如:

  1. 将函数中的print 语句替换为外部代码。
  2. 让您的方法可测试。
  3. 单元测试。
  4. 好东西:D

【讨论】:

  • 绝对是首选方法,也是我的做法。不过,对于第一次学习传递变量,还是有一些话要说的。
  • @PauloBu 这真是太棒了。我以前在课堂上工作过一点,但没有将它应用到我的程序中的知识。这是一个很大的帮助!但是,当我让用户在 body 函数中使用以下两行键入自己的代码时,我该怎么做 self.doc:code = input("") 和 doc.write('{0}\n'.format(code ))。我不能在课堂上写 self.doc.write
  • 我在您的问题中没有看到最后一个代码。在任何情况下,HtmlBuilder 类都将作为所有文档 I/O 的包装器。如果您需要doc.write,请在您的类中定义一个方法write,并在其中调用self.doc.write。
【解决方案2】:

您的函数createHtml() 需要return doc,然后您可以将其传递给createTitle()。像这样的:

def createHtml():
    name = input("\nEnter the name for your HTML-page: ")   
    doc = open(name + ".html", 'w')
    return doc

那么在你的while循环中:

doc = createHtml()

然后你可以将它传递给其他函数:

createTitle(doc)

请注意,不必在每个函数中调用相同的东西。

【讨论】:

    猜你喜欢
    • 2019-10-29
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多