Pergunta

I'm having some trouble with a piece of code I'm currently writing.

With the following code I get the 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>

I know it's because the doc is only defined in the createHtml-function. But how do I get it to work if I want the same doc to work when called in a different function? I cant leave it out of the createHtml-function because it will mess up my program since I have a menu which allows the user to choose from the different functions. Like this:

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()

And the doc is defined by the name variable in:

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

Is there anyway to get doc from the createHtml-function to my other functions?

Foi útil?

Solução

What about wrapping the functions inside a class?

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()

And just use it like this:

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()

At the end of the day, this is a perfect use case for Object Oriented Programming isn't it? After this, a lot of good improvements can be done.

For example:

  1. Replace the print statements from the function to the outer code.
  2. Make your methods testable.
  3. Unit testing.
  4. GOOD STUFF :D

Outras dicas

Your function createHtml() function will need to return doc, which you can then pass to createTitle(). Something like this:

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

So then in your while loop:

doc = createHtml()

and then you can pass it to the other functions:

createTitle(doc)

Note that it doesn't have to be called the same thing in each function.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top