0

I want to define in Python 3.9 a class which gets as a parameter a dictionary or a list of arguments and sets the class attributes in the following matter:

  1. If the key name is passed in the argument it uses it to set the corresponding class attribute.
  2. If the key name is not passed, it sets the class attribute with a default value.

One way to do this is:

class example():
   def __init__(self, x=None, y=None):
       if x is None:
          self.x = "default_x"
       else:
          self.x = x
       if y is None:
          self.y = "default_y"
       else:
          self.y = y

or shortly (thank to matszwecja):

class example():
   def __init__(self, x="default_x", y="default_y"):
      self.x = x
      self.y = y

Is there a more Pythonic way to do so without hard-coding if to each parameter? I want some flexibility so that if I add another attribute in the future, I won't be needed to hard-code another if for it.

I want to declare a class with

class example():
   def __init__(kwargs):
     ?

Such as if I pass example(y="some", z=1, w=2) it will generate

self.x = "default_x"
self.y = "some"
self.z = 1
self.w = 2
9
  • x = 'default_x' instead of x=None? That's literally what default is for. Commented Dec 21, 2022 at 9:08
  • Yes, but I want that I can pass the argument in a dynamic way, so I won't need to specify the entire list of arguments in the header. Commented Dec 21, 2022 at 9:12
  • 1
    I don't understand how that changes anything. You're already doing the exact same thing, just setting it to None for some reason instead of the actual default value you want. Commented Dec 21, 2022 at 9:13
  • This is how I do it now. Is there an automated way to generate the list of self.x from the arguments? Commented Dec 21, 2022 at 9:22
  • 1
    Something like this? pythontutorial.net/python-oop/python-dataclass Commented Dec 21, 2022 at 9:39

2 Answers 2

1
class example():
    def __init__(self, x="default_x", y="default_y"):
        self.x = x
        self.y = y
Sign up to request clarification or add additional context in comments.

Comments

0

Consider using a dataclass to generate the boilerplatey __init__ method for you.

from dataclasses import dataclass


@dataclass
class Example:
    x: str = "default_x"
    y: str = "default_y"

If you need to provide a mutable default (say, a new empty list if no explicit list is provided), you can use dataclasses.field to explicitly create a field with a default factory; the dataclass decorator uses the Field object to generate the necessary code for the instance attribute.

from dataclasses import dataclass, field


@dataclass
class Example:
    x: str = "default_x"
    # Bad!
    # y: list[str] = []
    y: list[str] = field(default_factory=list)  # Good

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.