TransWikia.com

Return correct path if windows or linux

Code Review Asked by ProtractorNewbie on December 17, 2020

I have been trying to code something simple where I call a class with different functions to different paths,

if I call etc:

from lib.utils import GetAllPaths

path = GetAllPaths()
path.test()

with following code:

class GetAllPaths:
    """
    Return file and paths directions
    """

    if platform == "win32":

        def test(self):
            return "C:\Users\test.py"

        def test2(self):
            return "C:\Users\test2.py"

        def test_flag(self):
            # new_manual_url.flag
            return "C:\Users\*test.flag"

        def kill_flag(self):
            # kill_*.txt
            return "C:\Users\*kill_*.flag"

        def restart(self):
            # start_*.txt
            return "C:\Users\*start_*.flag"

    elif platform == "linux" or platform == "linux2":

        def test(self):
            return "/home/test.py"

        def test2(self):
            return "/home/test2.py"

        def test_flag(self):
            return "/home/*test.flag"

        def kill_flag(self):
            return "/home/*kill_*.flag"

        def restart(self):
            return "/home/*start_*.flag"

My problem here is that I run sometimes my code through Linux and sometimes through Windows, so I have created a if else statement if the script is ran through Linux or Windows,

however I do see huge potential to short this code by alot but I don’t know how to apply it where I can choose etc if its linux then use the correct path of "test" for linux or if its windows then use the correct path of "test" for windows

One Answer

I think you can lean on a class-variable to create your base paths, and then define the functions to use that variable:

import os
from sys import platform

class GetAllPaths:
    """
    Return file and paths directions
    """

    if platform == "win32":
        root = 'C:\Users'
    elif platform == 'linux':
        root = '/home'
    else:
        # Probably raise an exception here
        raise Exception(f"Platform {platform} not supported")

    def test(self):
        return os.path.join(self.root, "test.py")

    def test2(self):
        return os.path.join(self.root, "test2.py")

    def test_flag(self):
        # new_manual_url.flag
        return os.path.join(self.root, "*test.flag")

    def kill_flag(self):
        # kill_*.txt
        return os.path.join(self.root, "*kill_*.flag")

    def restart(self):
        # start_*.txt
        return os.path.join(self.root, "*start_*.flag")

Furthermore, you'll notice that I'm using os.path.join, this way you don't have to worry about hard-coding the path separators.

Even more DRY would be to use a decorator on each of these functions which cuts down on repeated code:

import os
from functools import wraps
from sys import platform


class GetAllPaths:
    if platform == "win32":
        root = 'C:\Users'
    elif platform == 'linux':
        root = '/home'
    else:
        # Probably raise an exception here
        raise Exception(f"Platform {platform} not supported")

    def _add_platform(f):
        @wraps(f)
        def wrapper(self):
            path = f(self)
            return os.path.join(self.root, path)
        return wrapper

    
    @_add_platform
    def test(self):
        return "test.py"

    
    @_add_platform
    def test2(self):
        return "test2.py"


    @_add_platform
    def test_flag(self):
        # new_manual_url.flag
        return "*test.flag"


    @_add_platform
    def kill_flag(self):
        # kill_*.txt
        return "*kill_*.flag"


    @_add_platform
    def restart(self):
        # start_*.txt
        return "*start_*.flag"

Ditch the class

Realistically, you don't need the class here. You can identify this by looking at how your functions are utilized. There's not any class or instance specific information being passed to your functions (decorator notwithstanding). This means that your class and a module are fairly indistinguishable. To see this without a class, you might put all of this code into a new file, say get_all_paths.py:

# get_all_paths.py
import os
from functools import wraps
from sys import platform


if platform == "win32":
    root = 'C:\Users'
elif platform == 'linux':
    root = '/home'
else:
    # Probably raise an exception here
    raise Exception(f"Platform {platform} not supported")


def add_platform(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        path = f(*args, **kwargs)
        return os.path.join(root, path)
    return wrapper


@add_platform
def test():
    return "test.py"


@add_platform
def test2():
    return "test2.py"


@add_platform
def test_flag():
    # new_manual_url.flag
    return "*test.flag"


@add_platform
def kill_flag():
    # kill_*.txt
    return "*kill_*.flag"


@add_platform
def restart():
    # start_*.txt
    return "*start_*.flag"

Where now, you can use your functions through a global import:

import get_all_paths as g

g.test()
'/home/test.py'
```

Correct answer by C.Nivs on December 17, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP