【Think Python】Python笔记(十五)类和对象

面向对象编程:即使用程序员自己定义的类来组织代码和数据

(一)自定义类

  • 程序员自己定义的类称之为类(class)
  • 自己定义一个类是比较复杂的,但是它的优势是很明显的;
  • 可以在一个类中定义函数和变量;
class Point:
    """
    Represents a point in 2-D space.
    """
  • 像上面这样创建一个类对象(class object)
>>> Point
<class '__main__.Point'>

由于Point是定义在顶层的,所以全名是__main__.Point

  • 类对象实际上就如同一个创建对象的工厂【所谓万事万物皆对象,在大型的系统中,所有的代码都要是通过创建对象的方式】
# 如果要创建一个点,则可以像调用函数那样调用'Point'
>>> blank = Point()
>>> blank
<__main__.Point object at 0xb7e9d3ac>
  • 创建一个新的对象的过程称之为实例化(instantiation),新的对象叫做这个类的实例(instance)

(二)属性

使用点标记法对一个实例进行赋值:

>>> blank.x = 3.0
>>> blank.y = 4.0
  • 一个类中已经命名的一类元素叫做属性(attributes)

  • 下面是一张说明一个对象及其属性的状态图——对象图

>>> blank.y
4.0
>>> blank.x
3.0
  • 可以在任何表达式中使用点标记法:
>>> '(%g, %g)' % (blank.x, blank.y)
'(3.0, 4.0)'
>>> distance = math.sqrt(blank.x**2 + blank.y**2)
>>> distance
5.0
  • 实例也可以作为参数进行传递:
def print_point(p):
    print('(%g, %g)' % (p.x, p.y))
    
>>> print_point(blank)
(3.0, 4.0)
  • 在这个函数内部,pblank的别名,所以如果函数修改了pblank也会改变;

(三)定义矩形类

class Rectangle:
    """Represents a rectangle
    attributes: width, height, corner
    """

创建一个实例:

box = Rectangle()
box.width = 100.0
box.heighgt = 200.0
box.corner = Point()
box.corner.x = 0.0
box.corner.y = 0.0

(四)实例作为返回值

def find_center(rect):
    p = Point()
    p.x = rect.corner.x + rect.width/2
    p.y = rect.corner.y + rect.height/2
    return p

(五)对象是可变的

可以通过给一个对象的属性赋值来改变这个对象的状态:

box.width = box.width + 50
box.height = box.height +100
  • 可以编写函数来修改对象:
def grow_rectangle(rect, dwidth, dheight):
    rect.width += dwidth
    rect.height += dheight
    
>>> box.width, box.height
(150.0, 300.0)
>>> grow_rectangle(box, 50, 100)
>>> box.width, box.height
(200.0, 400.0)

(六)复制

别名会降低程序的可读性,因为一个地方的改变会对另一个地方产生意料之外的影响;

  • 通常,用复制对象的方法取代为对象起别名;如使用copy模块:
>>> p1 = Point()
>>> p1.x = 3.0
>>> p1.y = 4.0

>>> import copy
>>> p2 = copy.copy(p1)
#p1和 p2 拥有相同的数据,但是它们并不是同一个 Point 对象。
>>> print_point(p1)
(3, 4)
>>> print_point(p2)
(3, 4)
>>> p1 is p2
False
>>> p1 == p2
False
  • 但是,这个复制仅仅复制了 Rectangle对象,但是并没有复制Point对象:
>>> box2 = copy.copy(box)
>>> box2 is box
False
>>> box2.corner is box.corner
True

这种复制方式称之为浅复制

  • 实际上很多时候上面的复制方法并不是我们想要的,可以使用deepcopy方法:
>>> box3 = copy.deepcopy(box)
>>> box3 is box
False
>>> box3.corner is box.corner
False

(七)调试

  • 对象中新的异常:访问不存在的属性
>>> p = Point()
>>> p.x = 3
>>> p.y = 4
>>> p.z
AttributeError: Point instance has no attribute 'z'
  • 使用type检查一个对象的类型
>>> type(p)
<class '__main__.Point'>
  • 使用isinstance检查某个对象是不是某个类的实例
>>> isinstance(p, Point)
True
  • 使用内置函数hasattr检查对象是不是含有某个属性:
>>> hasattr(p, 'x')
True
>>> hasattr(p, 'z')
False
  • 使用try检查某个对象是不是我们所需要的的属性:
try:
    x = p.x
except AttributeError:
    x = 0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值