Python - Do I need a class or are these functions okay? I'm fairly new to Python but had to start using it and for reasons I have to use 2.7, which is why I am using that syntax. I have this function which gets data from a file, if it exists, and then gets passed onto other functions to perform SQL queries etc. The script is only intended to work for the directory it is running in, hence the os.getcwd()
This static data is the only data that gets looked up then returned and referenced by other functions. It works as it is but would you say for professionalism and understanding python better that a class would be better here or a restructure in someway? I am of course only posting a snippet.
    currentdirectory = os.getcwd()
    versionf = &quot;version.ini&quot;
    verfile = os.path.join(currentdirectory, versionf)
    
    def main():
       get_local_details()
       push_app(application, version)
       do_something(app_name_version)
    
    def get_local_details():
        if os.path.isfile(verfile):
            def get_app_name():
                try:   
                    global application
                    application = subprocess.check_output(['grep', 'application', verfile]).strip('\n')
                    application = application.rsplit('=')[1]
                    return application
                except:
                    print &quot;Application missing from version.ini&quot;
             def version_number():
                try: 
                    global version
                    version = subprocess.check_output(['grep', 'version', verfile]).strip('\n')
                    version = version.rsplit('=')[1]
                    return version
                except:
                    print &quot;version missing from version.ini&quot;
            get_app_name()
            version_number()
            def app_name_version(application, version)
                try:
                    global applicationver
                    applicationver = application + &quot;.&quot; + version
                    return applicationver
                except:
                    print &quot;error here&quot;
            app_name_version(application, version)  
        else:
            print &quot;File does not exist.&quot;

main()

contents of ini file are
application=testapp
version=1.0

do_something is a function that contains a SQL query that uses the app_name_version as the WHERE statement.
Is it even possible to use a function within a class to define the attributes?
Wow, this is kind of a mess.
I'll just review items in sequence as I read them.
My short answer, tl;dr: Yes!
Try executing python 2.7 code with a python 3 interpreter,
even if only during development on your laptop, or in unit tests.
It will give you the confidence to import six or otherwise drag
ancient code kicking and screaming into the modern era.
Small changes like print x → print(x) are easy and helpful.
The first three lines are nice.
We define currentdirectory, versionf, &amp; verfile as top-level module constants.
PEP-8 prefers the name current_directory, but I quibble, it's fine as-is.
You conditionally def or print.
I recommend an early abort:
            if not os.path.isfile(verfile):
                raise FileNotFoundError(verfile)

You have unfortunate coupling in this code.
Python, like all O-O languages, offers you structuring tools to improve cohesion.
Please avoid the global keyword, it is a bad code smell.
And please avoid nested def, as its effect on namespaces is similar to using global variables.
For private helpers, choose _private names like def _get_app_name,
def _version_number, and def _app_name_version.
You wrote:

application = subprocess.check_output(['grep', 'application', verfile]) ...


In several places you reference verfile.
Just listen to your code.
Clearly it is telling you it wants an __init__ constructor
which assigns to self.verfile, so that it may be used here.
Also, fork'ing grep is a tool one might use,
but it's not the most appropriate one for the task at hand.
Let me introduce you to import configparser.

                global application
                ...
                return application


Ok, you used to have 3 module-level variables,
and now you've added a 4th one.
Sadly, you have scattered them all around the module,
and you will continue to define additional ones.
This is poorly structured.
There's no central place for a maintenance engineer
to discover &quot;what are the important pieces of state I need to worry about?&quot;
Also, not sure why, after side effecting the variable,
you bothered to return it, since caller ignores the return value.
Rather than no-arg invocations of get_app_name and version_number,
you might consider passing in the values they need as arguments.
But if you turn this into a class, then self can supply those values.

            except:
                print ...


Better for your catch to be except Exception,
lest you accidentally catch CTRL-C exceptions, as well.
Consider using a logger.
Then we continue to see a pattern of &quot;more of the same&quot;,
I won't belabor it with repetition.
You are consistently abusing namespaces,
relying on implicit args,
and side effecting globals at module-level.
It's not quite clear from the generic code you posted,
but I'm going to go out on a limb and say that this module
seems to be about &quot;app verification&quot;.

Please do this:
class AppVerifier:

and then define half a dozen object attributes as I suggested above.
Doing just that one thing will have a huge effect on making your
code more maintainable for the next engineer that has to interact with it.