Home > OS >  How to define new attribute in python class?
How to define new attribute in python class?

Time:11-10

I wrote a class like which has 3 hidden attributres:

class Car():
    def __init__(self, name, model, brand):
        self.__name = name
        self.__model = model
        self.__brand = brand

Is that possible to create a method for this class to set a new attribute (publisher)? I wrote this one, but I didn't get result:

    def set_publisher(self, publisher):
        self.__publisher = publisher


b1 = Car(name="X", model="Y", brand="Z")
publisher="D"
b1.set_publisher(publisher)

Error:

AttributeError: 'Car' object has no attribute 'set_publisher'

CodePudding user response:

There is no problem if set_publisher is correctly defined as an instance method.

class Car:
    def __init__(self, name, model, brand):
        self.__name = name
        self.__model = model
        self.__brand = brand

    def set_publisher(self, publisher):
        self.__publisher = publisher

But if the setter does nothing but allow any value to be assigned directly to the attribute, why bother hiding it? Just make publisher a public attribute:

class Car:
    def __init__(self, name, model, brand, publisher=None):
        self.__name = name
        self.__model = model
        self.__brand = brand
        self.publisher = None  # Define but None is usually better than undefined

c = Car("Dave", "Model T", "Ford")
c.publisher = "Henry"

If you later decide to impose further restrictions on how (or if) the publisher can be set, you can replace it with a property without changing the interface of your class.

class Car:
    def __init__(self, name, model, brand, publisher=None):
        self.__name = name
        self.__model = model
        self.__brand = brand
        self._publisher = None

    @property
    def publisher(self):
        return self._publisher

    @publisher.setter
    def publisher(self, value):
        # If you want to examine value and reject it,
        # do so and raise a ValueError. You can modify
        # value before assigning it as well.

        if value == "Bob":
            raise ValueError("Bob is not a publisher")
        if value == "Alice":
            # Alice changed her name a while ago
            value = "Carol"
        self._publisher = value

c = Car("Dave", "Model T", "Ford")
c.publisher = "Henry"  # OK
c.publisher = "Alice"  # assert c.publisher == "Carol"
c.publisher = "Bob"  # ValueError

CodePudding user response:

You can try this code to use a method (wrapper of setattr) to add attributes by name and value:


class Car:
    def __init__(self, name, model, brand):
        self.__name = name
        self.__model = model
        self.__brand = brand

    def set_attribute(self, attr_name, value):
        setattr(self, attr_name, value)


obj = Car(name="name", model="model", brand="brand")
obj.set_attribute("__publisher", "publisher")
print(obj.__publisher)

>>> publisher
  • Related