class Student:
def __init__(self, name, age):
self.__name = name
self.__age = age
def study(self, course_name):
print(f'{self.__name}正在学习{course_name}.')
stu = Student('王大锤', 20)
stu.study('Python程序设计')
print(stu.__name) # AttributeError: 'Student' object has no attribute '__name'
上面代码的最后一行会引发AttributeError(属性错误)异常,异常消息为:'Student' object has no attribute '__name'。由此可见,以__开头的属性__name相当于是私有的,在类的外面无法直接访问,但是类里面的study方法中可以通过self.__name访问该属性。需要说明的是,大多数使用 Python 语言的人在定义类时,通常不会选择让对象的属性私有或受保护,正如有一句名言说的:“We are all consenting adults here”(大家都是成年人),成年人可以为自己的行为负责,而不需要通过 Python 语言本身来限制访问可见性。事实上,大多数的程序员都认为开放比封闭要好,把对象的属性私有化并非必不可少的东西,所以 Python 语言并没有从语义上做出最严格的限定,也就是说上面的代码如果你愿意,用stu._Student__name的方式仍然可以访问到私有属性__name,有兴趣的读者可以自己试一试。
class Triangle(object):
"""三角形"""
def __init__(self, a, b, c):
"""初始化方法"""
self.a = a
self.b = b
self.c = c
@staticmethod
def is_valid(a, b, c):
"""判断三条边长能否构成三角形(静态方法)"""
return a + b > c and b + c > a and a + c > b
# @classmethod
# def is_valid(cls, a, b, c):
# """判断三条边长能否构成三角形(类方法)"""
# return a + b > c and b + c > a and a + c > b
def perimeter(self):
"""计算周长"""
return self.a + self.b + self.c
def area(self):
"""计算面积"""
p = self.perimeter() / 2
return (p * (p - self.a) * (p - self.b) * (p - self.c)) ** 0.5
if Triangle.is_valid(3, 4, 5):
t = Triangle(3, 4, 5)
print(f'周长: {t.perimeter()}')
print(f'面积: {t.area()}')
else:
print('无效的边长!!!')
class Triangle(object):
"""三角形"""
def __init__(self, a, b, c):
"""初始化方法"""
self.a = a
self.b = b
self.c = c
@staticmethod
def is_valid(a, b, c):
"""判断三条边长能否构成三角形(静态方法)"""
return a + b > c and b + c > a and a + c > b
@property
def perimeter(self):
"""计算周长"""
return self.a + self.b + self.c
@property
def area(self):
"""计算面积"""
p = self.perimeter / 2
return (p * (p - self.a) * (p - self.b) * (p - self.c)) ** 0.5
if Triangle.is_valid(3, 4, 5):
t = Triangle(3, 4, 5)
print(f'周长: {t.perimeter}')
print(f'面积: {t.area}')
else:
print('无效的边长!!!')