简体   繁体   中英

Class argument's default value equal to another argument

I have a class where I want to have multiple file paths as an optional parameter, but the default value should have another parameter in it. Is there a better way to do this instead of checking for None 4 times? Also it outputs an error if you set the parameter. The default is working fine.

I basically want it like: you have this class, and you can set file paths if you want but if you don't set it its default is {name}_something .

from typing import Optional

class Test():
    def __init__(
        self,
        name: str,
        num: Optional[str] = None,
        DIR_A: Optional[str] = None,
        DIR_B: Optional[str] = None,
        ANOTHER_DIR: Optional[str] = None,
        DIR_2: Optional[str] = None,
    ) -> None:
        if DIR_A is None:
            self.DIR_A = f"{name}_Test"

        if DIR_B is None:
            self.DIR_B = f"{name}_ThisisalsoaTest"

        if ANOTHER_DIR is None:
            self.ANOTHER_DIR = f"{name}_TestNr3"

        if DIR_2 is None:
            self.DIR_2 = f"{name}_Test4ig"

        

    def get_files(self):
        print(self.DIR_A)


test = Test(name="test", num="12345", DIR_A="test")
test.get_files()

You can iterate through the list of FILES_* arguments, test and replace if None and use setattr to set them as attribute with whatever value.

It is however left for you to decide whether this is readable enough as readability is always better than cleverness.

from typing import Optional

class Test():
    def __init__(
        self,
        name: str,
        num: Optional[str] = None,
        FILES_1: Optional[str] = None,
        FILES_2: Optional[str] = None,
        FILES_3: Optional[str] = None,
        FILES_4: Optional[str] = None,
    ) -> None:
        for i, file in enumerate([FILES_1, FILES_2, FILES_3, FILES_4], 1):
            if file is None:
                file = f"{name}_File_{i}"
            setattr(self, f"FILES_{i}", file)

    def get_files(self):
        print(self.FILES_1)
        print(self.FILES_2)
        print(self.FILES_3)
        print(self.FILES_4)


test = Test(name="test", num="12345", FILES_1="myfile")
test.get_files()

Or after OP's edit, and with a fair bit of added complexity.

class Test:
    def __init__(
        self,
        name: str,
        num: Optional[str] = None,
        DIR_A: Optional[str] = None,
        DIR_B: Optional[str] = None,
        ANOTHER_DIR: Optional[str] = None,
        DIR_2: Optional[str] = None,
    ) -> None:
        defaults = [
            f"{name}_Test",
            f"{name}_ThisisalsoaTest",
            f"{name}_TestNr3",
            f"{name}_Test4ig",
        ]
        attrs = ["DIR_A", "DIR_B", "ANOTHER_DIR", "DIR_2"]
        args = [DIR_A, DIR_B, ANOTHER_DIR, DIR_2]
        for arg, at, default in zip(args, attrs, defaults):
            if arg is None:
                arg = default
            setattr(self, at, arg)

    def get_files(self):
        print(self.DIR_A)
        print(self.DIR_B)
        print(self.ANOTHER_DIR)
        print(self.DIR_2)

PS. typing.Optional[X] is equivalent to X | None X | None , which I find a lot more readable and saves an import.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM