动态属性
在Python中,我们可以动态为对象添加属性,这是Python作为动态类型语言的一项特权,代码如下所示。
注意:对象的方法其实本质上也是对象的属性,如果给对象发送一个无法接收的消息,引发的异常仍然是
AttributeError
。
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
stu = Student('王其', 20)
# 为Student对象动态添加sex属性
stu.sex = '男'
如果不希望在使用对象时动态的为对象添加属性,可以使用Python的__slots__
魔法。对于Student
类来说,可以在类中指定__slots__ = ('name', 'age')
,这样Student
类的对象只能有name
和age
属性,如果想动态添加其他属性将会引发异常,代码如下所示。
class Student:
__slots__ = ('name', 'age')
def __init__(self, name, age):
self.name = name
self.age = age
stu = Student('王其', 20)
# AttributeError: 'Student' object has no attribute 'sex'
stu.sex = '男'
静态方法和类方法
定义一个三角形类,可以根据三边求面积和周长。
在创建三角形对象时,传入的三条边长未必能构造出三角形,为此我们可以先写一个方法来验证给定的三条边长是否可以构成三角形,这种方法很显然就不是对象方法,因为在调用这个方法时三角形对象还没有创建出来。我们可以把这类方法设计为静态方法或类方法,也就是说这类方法不是发送给三角形对象的消息,而是发送给三角形类的消息,
import math
class Triangle:
def __init__(self, a, b, c):
if not Triangle.is_valid(a, b, c):
raise ValueError('无效的边长')
self.a = a
self.b = b
self.c = c
# @classmethod
# def is_valid(cls, a, b, c):
# return a + b > c and a + c > b and b + c > a
@staticmethod
def is_valid(a, b, c):
return a + b > c and a + c > b and b + c > a
def perimeter(self):
return self.a + self.b + self.c
def area(