Search code examples
pythonvariablespafy

Use a variable from one function within another function with Python


I have a program that downloads video files Here it is in full, don't worry its a short program.

import pafy

def download():
    url = raw_input('Please enter the path to the video\n')
    video = pafy.new(url)
    vid_title = video.title
    best = video.getbest()
    streams = video.streams
    print(vid_title)
    for stream in streams:
        print(stream)
    print'Resolution: ',best.resolution,'\nExtension : ', best.extension
    user_choice = raw_input("Do you want to download this video\ny or n\n")
    if user_choice == 'y':
        print'Your video will downloaded soon'
        filename = best.download(filepath = '/home/mark/new_projects')
        another_download()
    elif user_choice =='n':
        print'You have chosen not to download a video'
        another_download()


def another_download():
    another_choice = raw_input('Would you like to download another video\ny or n\n')
    if another_choice == 'y':
        download()
    else:
        print'Thank for using my program'

download()

I would like to break it down into smaller functions. I have tried to do this:

def url():
    url = raw_input('Please enter the path to the video\n')
    video = pafy.new(url)
    vid_title = video.title
    best = video.getbest()
    streams = video.streams
    print(vid_title)
    for stream in streams:
        print(stream)
    print'Resolution: ',best.resolution,'\nExtension : ', best.extension

def download():
    user_choice = raw_input("Do you want to download this video\ny or n\n")
    if user_choice == 'y':
        print'Your video will downloaded soon'
        filename = best.download(filepath = '/home/mark/new_projects')
        another_download()
    elif user_choice =='n':
        print'You have chosen not to download a video'
        another_download()

But when I try this I get an error telling me that best has not been declared. I don't want to declare best as a global variable. Is there a way of using a variable from one function inside another function?


Solution

  • There are a couple options for you here. I will try and lay them out best I can.

    Option 1: Assuming you are calling download() first, you can have url() return what you need and store that in a variable in the download() method:

    def url():
        url = raw_input('Please enter the path to the video\n')
        video = pafy.new(url)
        vid_title = video.title
        best = video.getbest()
        streams = video.streams
        print(vid_title)
        for stream in streams:
            print(stream)
        print'Resolution: ',best.resolution,'\nExtension : ', best.extension
        return best
    
    def download():
        user_choice = raw_input("Do you want to download this video\ny or n\n")
        if user_choice == 'y':
            best = url()
            print'Your video will downloaded soon'
            filename = best.download(filepath = '/home/mark/new_projects')
            another_download()
        elif user_choice =='n':
            print'You have chosen not to download a video'
            another_download()
    

    Option 2: You could use global variables, though I don't know the ramifications of using them in this case:

    best = None
    def url():
        global best
        url = raw_input('Please enter the path to the video\n')
        video = pafy.new(url)
        vid_title = video.title
        best = video.getbest()
        streams = video.streams
        print(vid_title)
        for stream in streams:
            print(stream)
        print'Resolution: ',best.resolution,'\nExtension : ', best.extension
    
    def download():
        global best
        user_choice = raw_input("Do you want to download this video\ny or n\n")
        if user_choice == 'y':
            print'Your video will downloaded soon'
            filename = best.download(filepath = '/home/mark/new_projects')
            another_download()
        elif user_choice =='n':
            print'You have chosen not to download a video'
            another_download()
    

    I think either of these solutions will give you what you want, but I would recommend the first in this specific case as it doesn't seem like a complex program.