特性(property)

property是一种特殊的属性,访问它时会执行一段函数,然后返回一个值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import math 

class Circle:
def __init__(self, radius):
self.radius = radius

@property
def area(self):
return math.pi * self.radius**2

@property
def perimeter(self):
return 2 * math * math.pi * self.radius

# 实例化
circle = Circle(10)
print(circle.radius)
# 有了@property这个装饰器,此时可以向属性一样去访问area和perimeter
print(circle.area)
print(circle.perimeter)

注意:

使用了@property装饰器的话。此时的特性area和perimeter不能被赋值

property的目的

将一个类函数定义成特性之后,对象再去使用obj.name的时候,根本不会意识到name是执行了一个函数之后返回的结果,这种特性的使用方式遵循了统一访问的原则
在Java和C++的面相对象中的封装有三种方式:

  • public:对外公开,其实就是不封装
  • protected:这种封装对外不开放,但是对成员函数、父类、子类公开
  • private:这种封装对谁都不公开

Python并没有将这三种封装方式集成到自己的面相对象class机制中,在C++中面向对象一般会将所有的数据设置为私有,然后提供set和get的方法(接口)去进行设置和获取,在Python中可以使用property的方法进行实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Student(object):
def __init__(self, name, score):
self.name = name
self.__score = score
@property
def score(self):
return self.__score
@score.setter
def score(self, score):
if score < 0 or score > 100:
raise ValueError('invalid score')

# 实例化
student = Student('Bob', 80)
# 对score进行赋值,实际上是调用的 @score.setter
student.score = 60
# 输出score实际上是调用的 @property
print(student.score)

str的用法

__str__定义在类的内部,必须返回一个字符串,当打印这个类的实例化独享的时候会触发__str__函数。

1
2
3
4
5
6
7
8
9
10
11
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return 'name:{}, age:{}'.format(name, age)

# 实例化
people = People('Mike', 18)
# 触发__str__
print(people)