from dataclasses import dataclass
"""
手动定义 getter 和 setter 方法可以更加灵活地处理属性的值,并且可以进行各种数据验证和转换操作。
但是,这也会增加代码的复杂度,并使得类定义更加冗长。因此,在处理简单的数据时,
建议使用 dataclass 装饰器,而在处理复杂的数据时,可以考虑手动定义 getter 和 setter 方法。
"""
# dataclass 装饰器
@dataclass
class User:
name: str
age: int = 30
password: str = "1234"
def say_hello(self):
print(f"my name is {self.name}")
u = User('1', 20)
print(u)
u.name = "james"
print(u)
u.say_hello()
# 手动定义 getter 和 setter 方法
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
@property
def name(self):
return self._name
@property
def age(self):
return self._age
@name.setter # 允许你对已用@property装饰的函数赋值
def name(self, value):
self._name = value
@age.setter # 允许你对已用@property装饰的函数赋值
def age(self, value):
if value < 0:
raise ValueError("Age 不能为负")
self._age = value
def say_hello(self):
print(f"Hello, my name is {self.name}, and I am {self.age} years old.")
person = Person("xiaoming", 20)
# 也能修改 但是不建议
# print(person._age)
# person._age = 30
# print(person._age, person._name)
# setattr修改
# setattr(person, '_age', 50)
# person.say_hello()
# setattr装饰器修改
person.age = 50
person.say_hello()
内部使用的属性和方法和私有方法定义和区别
在 Python 中,以单下划线 _ 开头的属性和方法是被定义为内部使用的属性和方法,它们不应该被外部代码直接访问。
而以双下划线 __ 开头的属性和方法则是被定义为私有的属性和方法,它们只能由类内部访问。
需要注意的是,在使用双下划线 __ 定义私有属性时,Python 会进行名称修饰(Name Mangling)。具体来说,
Python 会将其转换为 _classname__name 的形式,其中 classname 是类的名称,name 是属性的名称。这样做是为了防止子类意外覆盖父类的属性或方法。
以下是一个示例代码,展示如何使用 _ 和 __ 定义属性:
class Person:
def __init__(self, name, age):
self._name = name # 以单下划线开头的属性
self.__age = age # 以双下划线开头的属性
person1 = Person('Alice', 30)
print(person1._name) # 输出:'Alice'
print(person1.__age) # 报错:AttributeError: 'Person' object has no attribute '__age'
print(person1._Person__age) # 输出:30
在上述代码中,我们首先定义了一个 Person 类,并在 init() 方法中初始化了 _name 和 __age 属性。然后,我们创建了一个 Person 对象 person1,并尝试访问它们的值。我们可以看到,我们能够通过 _name 属性直接获取它的值,但是如果直接访问 __age 属性,则会引发 AttributeError 异常。这是因为 Python 对其进行了名称修饰,需要使用 _Person__age 的形式才能访问它的值。
需要注意的是,虽然以 _ 和 __ 开头的属性和方法是被定义为内部使用的,但是外部代码仍然可以访问它们,并且可以覆盖它们的值。因此,在设计类时,应该明确标记哪些属性和方法是公共的,哪些是内部使用或私有的,并且遵循良好的编程习惯来保护它们。