关于程序员:Python-类的私有属性和私有方法

48次阅读

共计 5167 个字符,预计需要花费 13 分钟才能阅读完成。

本文首发自「慕课网」,想理解更多 IT 干货内容,程序员圈内热闻,欢送关注!

作者 | 慕课网精英讲师 朱广蔚

在 Python 的面向对象编程中,公有属性是只能在类的实例办法中拜访的属性,不容许在外界拜访公有属性。

  1. 公有属性的定义
    1.1 定义
    在属性名称前加上前缀 __,示意该属性为公有属性,示例代码如下:

class Object:

def method(self):
    self.__private_attribute = 123

代码块 123
在第 3 行,创立一个公有属性 __private_attribute。

1.2 在类外读取公有属性
只能在类的实例办法中拜访公有属性,不容许在类的内部拜访公有属性,示例代码如下:

class Person:

def __init__(self, name):
    self.__name = name

tom = Person(‘tom’)
print(tom.__name)
代码块 123456
在第 1 行,定义了类 Person
在第 3 行,创立公有属性 __name
在第 5 行,创立一个实例 tom
在第 6 行,间接拜访实例的属性 __name
程序运行输入如下:

Traceback (most recent call last):
File “attr-get.py”, line 6, in <module>

print(tom.__name)

AttributeError: ‘Person’ object has no attribute ‘__name’
代码块 1234
程序运行报错:‘Person’object has no attribute‘__name’,示意无奈找到属性 __name’。因而,在类 Person 的内部无奈间接读取实例的公有属性。

1.3 在类外批改公有属性
1.2 大节的例子,在类外读取公有属性;本节的例子,在类外批改公有属性。示例代码如下:

class Person:

def __init__(self, name):
    self.__name = name

def get_name(self):
    return self.__name

tom = Person(‘tom’)
tom.__name = ‘jerry’
print(tom.get_name())
代码块 12345678910
在第 1 行,定义了类 Person 在第 3 行,创立公有属性 __name 在第 6 行,在类的实例办法 get_name 中,拜访公有属性 __name
在第 8 行,创立一个实例 tom 在第 9 行,将实例的属性 __name 批改为‘jerry’在第 10 行,通过实例办法 get_name 读取公有属性 __name
程序运行输入如下:

tom
代码块 1
程序在第 9 行,将实例的公有属性 __name 批改为‘jerry’,然而程序输入表明:在类的外部,公有属性 __name 没有发生变化。因而,在类 Person 的内部无奈间接批改实例的公有属性。

1.4 通过 set/get 办法拜访公有属性
本节在类的内部拜访公有属性的办法,代码如下:

class Person:

def __init__(self, name):
    self.__name = name

def get_name(self):
    return self.__name

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

tom = Person(‘tom’)
tom.set_name(‘jerry’)
print(tom.get_name())
代码块 12345678910111213
在第 1 行,定义了类 Person 在第 3 行,创立公有属性 __name 在第 5 行,创立办法 get_name,它读取公有属性 __name 在第 8 行,创立办法 set_name,它批改公有属性 __name
在第 11 行,创立一个实例 tom 在第 12 行,通过实例办法 get_name 读取公有属性 __name 在第 13 行,通过实例办法 set_name 批改公有属性 __name
程序输入后果如下:

jerry
代码块 1
程序输入表明,通过办法 tom.set_name(‘jerry’) 胜利的将公有属性 __name 设置为 jerry。因而,在类的内部通过 get/set 办法拜访公有属性。

  1. 公有属性的利用
    2.1 概述
    数学中的线段领有 3 个属性:

start,示意开始地位
end,示意完结地位
length,示意线段的长度,等于 end – start
当批改属性 start 时,属性 length 会发生变化;当批改属性 end 时,属性 length 也会发生变化;如果批改属性 start 或者 end 时,遗记批改属性 length 的话,则会造成逻辑谬误,示例代码如下:

class Segment:

def __init__(self, start, end):
    self.start = start
    self.end = end
    self.length = self.end - self.start

def show(self):
    print('start = %d, end = %d, length = %d' % (self.start, self.end, self.length))

segment = Segment(10, 100)
segment.start = 20
segment.show()
代码块 123456789101112
在第 2 行,定义构造方法在第 5 行,应用属性 start 和 end 计算属性 length
在第 7 行,定义方法 show,打印属性 start、end、length
在第 10 行,创立线段 segment,设置 start = 10,end = 100
在第 11 行,将 start 批改为 20
在第 12 行,调用办法 show 打印属性 start、end、length
程序运行输入后果如下:

start = 20, end = 100, length = 90
代码块 1
start 批改为 20 后,length 应该等于 80,然而程序输入表明 length 等于 90。因为 start 批改后,遗记批改 length,造成了这样的逻辑谬误。

2.2 应用公有属性解决问题
为了解决上个大节中的问题,将属性 start、end、length 设置为公有属性:

禁止在外界间接拜访这 3 个属性
只能通过对应的 get/set 办法拜访这 3 个属性
class Segment:

def __init__(self, start, end):
    self.__start = start
    self.__end = end
    self.__length = self.__end - self.__start

def get_start(self):
    return self.__start

def set_start(self, start):
    self.__start = start
    self.__length = self.__end - self.__start

def get_end(self):
    return self.__end

def set_end(self, end):
    self.__end = end
    self.__length = self.__end - self.__start

def get_length(self):
    return self.__start

def set_length(self, length):
    self.__length = length

def show(self):
    print('start = %d, end = %d, length = %d' % (self.__start, self.__end, self.__length))

segment = Segment(10, 100)
segment.set_start(20)
segment.show()
代码块 1234567891011121314151617181920212223242526272829303132
类 Segment,蕴含 3 个公有属性,读写这些属性的办法如下:

办法

性能

get_start

读取属性 start

set_start

设置属性 start

get_end

读取属性 end

set_end

设置属性 end

get_length

读取属性 length

set_length

设置属性 length

在第 12 行,在 set_start 办法中,批改属性 start 时,同时从新计算属性 length
在第 19 行,在 set_end 办法中,批改属性 end 时,同时从新计算属性 length
在 set 办法中,批改 start 和 end 属性时,同时批改 length 属性,从而保障了一致性,不会呈现上个大节中的逻辑谬误。
程序运行输入后果如下:

start = 20, end = 100, length = 80
代码块 1
输入表明,当属性 start 批改为 20 后,属性 length 被批改为 80,防止了上个大节中的谬误。

  1. 公有办法的定义
    3.1 定义
    在 Python 的面向对象编程中, 公有办法是只能在类的实例办法中拜访的办法,不容许在外界拜访公有办法。在办法名称前加上前缀 __,示意该办法为公有办法,示例代码如下:

class Object:

def __private_method(self):
    pass

代码块 123
在第 3 行,定义了一个公有办法 __private_method。

3.2 在类外拜访公有办法
公有办法只能在类的外部被调用,不容许在类的内部拜访。示例代码如下:

class Object:

def __private_method(self):
    pass

object = Object()
object.__private_method()
代码块 123456
在第 2 行,定义了一个公有办法 __private_method
在第 5 行,创立一个实例 object
在第 6 行,调用实例的公有办法 __private_method
程序运行输入如下:

Traceback (most recent call last):
File “method-error.py”, line 6, in <module>

object.__private_method()

AttributeError: ‘Object’ object has no attribute ‘__private_method’
代码块 1234
程序运行报错:‘Object’object has no attribute‘__private_method’,示意无奈找到办法 __private_method’。因而,在类 Person 的内部无奈调用实例的公有办法。

  1. 公有办法的利用
    4.1 概述
    本节实现一个剖析文本的程序,文本由多个单词形成,单词之间应用空格隔开,单词的类型如下:

数字,例如 123
字母,例如 abc
操作符,例如 =、+、- 等符号
程序对文本剖析后,输入单词的类型和值,假如输出文本为 a = 123,则输入如下:

alpha a
operator =
digit 123
代码块 123
程序的思路如下:

定义方法 parse_string,它将文本宰割为多个单词
定义方法 parse_word,它判断并打印单词的类型
在办法 parse_string 中调用 parse_word 解决每个单词
办法 parse_word 用于辅助实现办法 parse_string,不须要被外界拜访,因而将其设定为公有办法。

4.2 应用公有办法解决问题
class Parser:

def __parse_word(self, word):
    if word.isdigit():
        print('digit    %s' % word)
    elif word.isalpha():
        print('alpha    %s' % word)
    elif word == '=' or word == '+' or word == '-':
        print('operator %s' % word)

def parse_string(self, string):
    words = string.split(' ')
    for word in words:
        self.__parse_word(word)

parser = Parser()
parser.parse_string(‘sum = sum + 100’)
代码块 12345678910111213141516
在第 2 行,定义公有办法 __parse_word,判断单词的类型在第 3 行,通过办法 isdigit 判断是否为数字在第 5 行,通过办法 isalpha 判断是否为字母
在第 10 行,定义公开办法 parse_string 在第 11 行,应用 split 将文本宰割为多个单词在第 13 行,循环调用公有办法 __parse_word 解决每个单词
在第 16 行,在类 Parser 的内部,调用公开办法 parse_string
实现办法 parse_string 是类 Parser 的接口,外界通过这个办法实现剖析文本的性能;而办法 __parse_word 是一个辅助办法,它用于实现办法 parse_string,不须要公开给外界调用,因而将它设定为公有办法。

程序运行输入如下:

alpha sum
operator =
alpha sum
operator +
digit 100
代码块 12345

欢送关注「慕课网」,发现更多 IT 圈优质内容,分享干货常识,帮忙你成为更好的程序员!

正文完
 0