An attribute is a named value associated with an object or class. In a Person instance, attributes such as fname, mname, and lname hold that person’s state; full_name() reads them to produce a name. section 4.1.1
class Person:
def __init__(self, fname: str, mname: str = None, lname: str = None):
self.fname = fname
self.mname = mname
self.lname = lname
def full_name(self) -> str:
full_name = self.fname
if self.mname is not None:
full_name = f"{full_name} {self.mname}"
if self.lname is not None:
full_name = f"{full_name} {self.lname}"
return full_name
See how the constructor assigns name attributes to self and how full_name() uses them. section 4.1.1
Plain attributes are the default for class design here. Python attributes and methods are public; properties can provide control over how attributes are accessed and used. section 4.1.1

























