python类的定义:手动定义getter和setter方法和使用dataclass装饰器的类

手动定义 getter 和 setter 方法可以更加灵活地处理属性的值,并且可以进行各种数据验证和转换操作。但是,这也会增加代码的复杂度,并使得类定义更加冗长。因此,在处理简单的数据时,建议使用 dataclass 装饰器,而在处理复杂的数据时,可以考虑手动定义 getter 和 setter 方法。

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 的形式才能访问它的值。
需要注意的是,虽然以 _ 和 __ 开头的属性和方法是被定义为内部使用的,但是外部代码仍然可以访问它们,并且可以覆盖它们的值。因此,在设计类时,应该明确标记哪些属性和方法是公共的,哪些是内部使用或私有的,并且遵循良好的编程习惯来保护它们。

你可能感兴趣的:(python,开发语言)