Python 笔记(18)— 类的私有属性读取和修改方法

先看下面代码:

class Movie(object):
    def __init__(self, name, year):
        self.name = name
        self.year = year

    def print_detail(self):
        print("Name is {}, year is {}".format(self.name, self.year))


movie = Movie("囧妈", 2020)
print(movie.name) # 囧妈

movie.name = "流浪地球"
print(movie.name) # 流浪地球

看到创建的两个属性和一个方法都被暴露在外面,可被 movie 调用。这样的话,这些属性就会被任意修改(电影名称由 【囧妈】变为【流浪地球】)。

要想类的属性不被任意修改,可以使用下面两种方法来解决:

  • 定义公共函数来访问和修改私有属性;
  • 使用 property 类来访问和修改私有属性;

1. 使用公共函数

分别定义公共函数来对私有属性进行访问和修改。

1.1 读取私有属性

如果想避免属性 name 被修改,可以将它变为私有变量。改动方法:属性前加 2 个 _ 后,变为私有属性。

  • 以单下划线开头(_foo )的代表不能直接访问的类属性,表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用 from xxx import * 导入;

  • 以双下划线开头的(__foo )代表类的私有成员(private)的变量,只能是允许这个类本身进行访问了。;

  • 以双下划线开头和结尾的(__ foo__)代表 Python 里特殊方法专用的标识,如 __init()__ 代表类的构造函数;

如:

class Movie(object):
    def __init__(self, name, year):
        self.__name = name
        self.__year = year

    def print_detail(self):
        print("Name is {}, year is {}".format(self.__name, self.__year))


movie = Movie("囧妈", 2020)
movie.print_detail()
print(movie.__name) # 囧妈

结果显示:

Name is 囧妈, year is 2020
...
AttributeError: 'Movie' object has no attribute '__name'

可以看到私有属性 __name 是无法直接访问的。

但是这样改动后,属性 __name 不能被访问了,也就无法得知 movie 的名字叫啥。不过,这个问题有一种简单的解决方法,直接新定义一个方法就行:

def get_name(self):
    return self.__name

综合代码如下:

class Movie(object):
    def __init__(self, name, year):
        self.__name = name
        self.__year = year

    def print_detail(self):
        print("Name is {}, year is {}".format(self.__name, self.__year))

    def get_name(self):
        return self.__name

movie = Movie("囧妈", 2020)
movie.print_detail()
print(movie.get_name()) # 囧妈

1.2 设置私有属性

class Movie(object):
    def __init__(self, name, year):
        self.__name = name
        self.__year = year

    def print_detail(self):
        print("Name is {}, year is {}".format(self.__name, self.__year))

    def get_name(self):
        return self.__name
    
    def set_name(self, name):
        self.__name = name

movie = Movie("囧妈", 2020)
movie.print_detail()
print(movie.get_name()) # 囧妈
movie.set_name("wohu")
print(movie.get_name()) # wohu

2. 使用 property 类

使用 Python 自带的 property 类,就会优雅地将 name 变为只读的。

2.1 读取私有属性

@property
def name(self):
   	return self.__name

完整代码如下:

class Movie(object):
    def __init__(self, name, year):
        self.__name = name
        self.__year = year

    def print_detail(self):
        print("Name is {}, year is {}".format(self.__name, self.__year))

    @property
    def name(self):
        return self.__name

movie = Movie("囧妈", 2020)
movie.print_detail()
print(movie.name) # 囧妈
#movie.name = "流浪地球"

2.2 设置私有属性

如果再尝试使用

movie.name = "流浪地球"

修改 name 属性时,会报如下错误:

Traceback (most recent call last):
    movie.name = "流浪地球"
AttributeError: can't set attribute

使用 @property 装饰后 name 变为属性,意味着 .name 就会返回电影的名字,而不是通过 .get_name() 这种函数调用的方法。这样变为真正的属性后,可读性更好。

如果使 name 既可读又可写,就再增加一个装饰器 @name.setter

class Movie(object):
    def __init__(self, name, year):
        self.__name = name
        self.__year = year

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, new_name):
        self.__name = new_name

movie = Movie("囧妈", 2020)
print(movie.name) # 囧妈
movie.name = "流浪地球"
print(movie.name) # 流浪地球

注意这种装饰器写法:name.settername 已经被包装为 property 实例,调用实例上的 setter 函数再包装 name 后就会可写。

  • 12
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
当我们需要在派生中新增私有属性并重写基方法时,可以使用以下步骤: 1. 定义一个派生,并在定义的开头使用基名称和圆括号,以便将基与派生联系起来。 2. 在派生中定义一个新的私有属性。 3. 在派生中重写基方法,可以使用 super() 函数调用基方法,并在其基础上添加新的功能。 下面是一个示例代码,演示了如何在 Python 中实现派生私有属性和重写基方法: ```python class BaseClass: def __init__(self, name): self.name = name def display(self): print("BaseClass Name:", self.name) class DerivedClass(BaseClass): def __init__(self, name, age): super().__init__(name) self.__age = age # 新增私有属性 def display(self): super().display() # 调用基方法 print("DerivedClass Age:", self.__age) # 添加新功能 d = DerivedClass("Tom", 20) d.display() ``` 在这个例子中,我们创建了一个 BaseClass,其中包含一个属性一个方法。然后我们创建了一个派生 DerivedClass,它继承了 BaseClass,并添加了一个新的私有属性。最后,我们重写了基方法,并在其中添加了新的功能。 需要注意的是,在派生中新增私有属性时,需要在属性的名称前加上两个下划线,这样属性就变成了私有属性,只能在内部访问。另外,当我们重写基方法时,可以使用 super() 函数调用基方法,并在其基础上添加新的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值