• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Python面向对象进阶学习

python 搞代码 4年前 (2022-01-09) 16次浏览 已收录 0个评论

在前面的章节我们已经了解了面向对象的入门知识,知道了如何定义类,如何创建对象以及如何给对象发消息。为了能够更好的使用面向对象编程思想进行程序开发,我们还需要对Python中的面向对象编程进行更为深入的了解。

@property装饰器

之前我们讨论过Python中属性和方法访问权限的问题,虽然我们不建议将属性设置为私有的,但是如果直接将属性暴露给外界也是有问题的,比如我们没有办法检查赋给属性的值是否有效。我们之前的建议是将属性命名以单下划线开头,通过这种方式来暗示属性是受保护的,不建议外界直接访问,那么如果想访问属性可以通过属性的getter(访问器)和setter(修改器)方法进行对应的操作。如果要做到这点,就可以考虑使用@property包装器来包装getter和setter方法,使得对属性的访问既安全又方便,代码如下所示。

class Person(object):

 def __init__(self, name, age):
  self._name = name
  self._age = age

 # 访问器 - getter方法
 @property
 def name(self):<i style="color:transparent">本文来源gaodai$ma#com搞$代*码*网(</i>
  return self._name

 # 访问器 - getter方法
 @property
 def age(self):
  return self._age

 # 修改器 - setter方法
 @age.setter
 def age(self, age):
  self._age = age

 def play(self):
  if self._age <= 16:
   print('%s正在玩飞行棋.' % self._name)
  else:
   print('%s正在玩斗地主.' % self._name)


def main():
 person = Person('王大锤', 12)
 person.play()
 person.age = 22
 person.play()
 # person.name = '白元芳' # AttributeError: can't set attribute


if __name__ == '__main__':
 main()

__slots__魔法

我们讲到这里,不知道大家是否已经意识到,Python是一门动态语言。通常,动态语言允许我们在程序运行时给对象绑定新的属性或方法,当然也可以对已经绑定的属性和方法进行解绑定。但是如果我们需要限定自定义类型的对象只能绑定某些属性,可以通过在类中定义__slots__变量来进行限定。需要注意的是__slots__的限定只对当前类的对象生效,对子类并不起任何作用。

class Person(object):

 # 限定Person对象只能绑定_name, _age和_gender属性
 __slots__ = ('_name', '_age', '_gender')

 def __init__(self, name, age):
  self._name = name
  self._age = age

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

 @property
 def age(self):
  return self._age

 @age.setter
 def age(self, age):
  self._age = age

 def play(self):
  if self._age <= 16:
   print('%s正在玩飞行棋.' % self._name)
  else:
   print('%s正在玩斗地主.' % self._name)


def main():
 person = Person('王大锤', 22)
 person.play()
 person._gender = '男'
 # AttributeError: 'Person' object has no attribute '_is_gay'
 # person._is_gay = True

静态方法和类方法

之前,我们在类中定义的方法都是对象方法,也就是说这些方法都是发送给对象的消息。实际上,我们写在类中的方法并不需要都是对象方法,例如我们定义一个“三角形”类,通过传入三条边长来构造三角形,并提供计算周长和面积的方法,但是传入的三条边长未必能构造出三角形对象,因此我们可以先写一个方法来验证三条边长是否可以构成三角形,这个方法很显然就不是对象方法,因为在调用这个方法时三角形对象尚未创建出来(因为都不知道三条边能不能构成三角形),所以这个方法是属于三角形类而并不属于三角形对象的。我们可以使用静态方法来解决这类问题,代码如下所示。

from math import sqrt


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

 def perimeter(self):
  return self._a + self._b + self._c

 def area(self):
  half = self.perimeter() / 2
  return sqrt(half * (half - self._a) *
     (half - self._b) * (half - self._c))


def main():
 a, b, c = 3, 4, 5
 # 静态方法和类方法都是通过给类发消息来调用的
 if Triangle.is_valid(a, b, c):
  t = Triangle(a, b, c)
  print(t.perimeter())
  # 也可以通过给类发消息来调用对象方法但是要传入接收消息的对象作为参数
  # print(Triangle.perimeter(t))
  print(t.area())
  # print(Triangle.area(t))
 else:
  print('无法构成三角形.')


if __name__ == '__main__':
 main()

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Python面向对象进阶学习
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址