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