何为定制类?

Python的class允许定义许多特殊方法,可以让我们非常方便地生成特定的类。在类中应用或者重写python的特殊方法,得到的类,就是定制类。

大家都知道print的用法。见下面例子

>>> lst = [2,3,4]
>>> print lst
[2, 3, 4]
>>> class Animal(object):
pass >>> a = Animal()
>>> print a
<__main__.Animal object at 0x01E6E990>

为什么print都能识别出lst和p的数据类型呢?

当我们执行如下代码的时候,就知道为什么了?

>>> print lst.__str__
<method-wrapper '__str__' of list object at 0x01E641E8>
>>> print a.__str__
<method-wrapper '__str__' of Animal object at 0x01E6E990>

__str__特殊方法,能识别出每一个数据类型。如果希望类的实例print a 打印出 ‘object of Animal class’.怎么办?重新定义__str__方法。

>>> class Animal(object):
def __str__(self):
return 'object of Animal class' >>> a = Animal()
>>> print a
object of Animal class

但是有时候发现直接敲

>>> a
<__main__.Animal object at 0x01E6E990>

__str__不会被调用。因为当直接敲a这行代码的时候,直接调用的并不是__str__.而是__repr__.

>>> class Animal(object):
def __str__(self):
return 'object of Animal class'
__repr__ = __str__ //偷懒一下 >>> a = Animal()
>>> a
object of Animal class

python的特殊方法很多,这里就不做一一介绍。下面主要介绍 __slots__,__call__,@property用法。

__slots__

python是一个动态语言,任何实例可以再运行期间都能动态添加实例的属性。但是有时候,想限制实例的添加属性,就使用__slot__方法。见下面例子:

>>> class Person(object):
__slots__ = ('name','age')//限制只有name和age的属性
def __init__(self,name,age):
self.name = name
self.age = age >>> p = Person('zhangsan',25)
>>> p.age
25
>>> p.name
'zhangsan'
>>> p.gender ='man'//直接动态赋属性gender,会出现错误 Traceback (most recent call last):
File "<pyshell#42>", line 1, in <module>
p.gender ='man'
AttributeError: 'Person' object has no attribute 'gender'

__slot__目的是限制当前类所能拥有的属性。所以在继承的环境下,子类不受影响。

>>> class Student(Person):
pass >>> s = Student('zhangsan',26)
>>> s.age
26
>>> s.name
'zhangsan'
>>> s.gender = 'man'//可以动态添加属性
>>> s.gender
'man'

所以子类Student如果想自己限制添加属性的话,也要通过__slots__来控制。

__call__

一个类的实例可以变成一个可调用的对象,只需要实现一个特殊的方法__call__就可以了。

接下来我们把Student类变成一个可调用的对象:

>>> class Student(Person):
def __init__(self,name,score):
self.name = name
self.score = score >>> class Student(Person):
def __init__(self,name,score):
self.name = name
self.score = score
def __call__(self,age):
print 'my name is %s'% self.name
print 'my age is %d'% age >>> s = Student('lixi',89)
>>> s(25)
my name is lixi
my age is 25

有时候你会发现s(25)乍一眼感觉不出来是一个函数还是对象的实例。python语言函数和对象的实例不是区分的很明显。

@property

上述的class Student中,当修改s实例的score值时,

>>> s.score = 89
>>> s.score = 9999

但是这样无法检查s实例的分数有效性。目前只能这样做:

>>> class Student(object):
def __init__(self,name,score):
self.name = name
self.__score = score
def set_score(self,score):
if score <0 or score >100:
raise ValueError('invalid score')
self.__score = score
def get_score(self):
return self.__score >>> s = Student('wangwu',89)
>>> s.set_score(89)
>>> s.set_score(9999) //非法值,ValueError Traceback (most recent call last):
File "<pyshell#75>", line 1, in <module>
s.set_score(9999)
File "<pyshell#71>", line 7, in set_score
raise ValueError('invalid score')
ValueError: invalid score

有时候觉得写s.set_score和s.get_score没有直接写s.score那么直接。有没有其他办法?既能直接的s.score又能检查score的有效性?python提供@property高阶函数这样功能需求的装饰器。

>>> 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')
self.__score = score >>> s = Student('liunx',98)
>>> s.score = 89
>>> s.score = 9999 Traceback (most recent call last):
File "<pyshell#82>", line 1, in <module>
s.score = 9999
File "<pyshell#79>", line 12, in score
raise ValueError('invalid score')
ValueError: invalid score

小结:

特殊方法:

1.任何数据实例都有特殊方法

2.特殊方法定义在class中

3.不需要直接调用

4.python的某些方法或者函数会直接调用数据实例的特殊方法

实现特殊方法:

1.重新编写用到的特殊方法

2.如果重新一些特殊方法,有些关联的特殊方法也要一并实现。例如:__setattr__,__getattr__,__delattr__

python学习第十七天 --定制类的更多相关文章

  1. Python:面向对象编程3 定制类(有更新)

    Python:面向对象编程3  定制类(有更新) ⚠️本文主要内容为对Data model相关知识点的提取学习记录.(内容来自文档和部分网页教程案例) ⚠️:这个连接指向<流畅的python&g ...

  2. Python学习第十五篇——类继承和类实例化

    学习Python类时,我们明白了类的本质,以及所谓的面向对象编程思想强调的对事物本身的属性,我们对某一类事物进行描述——采用了很多方法,这些方法描述了类的属性(比如猫科动物的眼睛,四肢,是否哺乳类等等 ...

  3. Python学习_13_继承和元类

    继承 继承的含义就是子类继承父类的命名空间,子类中可以调用父类的属性和方法,由于命名空间的查找方式,当子类中定义和父类同名属性或者方法时,子类的实例调用的是子类中的属性,而不是父类,这就形成了pyth ...

  4. 从0开始的Python学习012数据结构&对象与类

    简介 数据结构是处理数据的结构,或者说,他们是用来存储一组相关数据的. 在Python中三种内建的数据结构--列表.元组和字典.学会了使用它们会使编程变得的简单. 列表 list是处理一组有序的数据结 ...

  5. Python学习(七)面向对象 ——类和实例

    Python 面向对象 —— 类和实例 类 虽然 Python 是解释性语言,但是它是面向对象的,能够进行对象编程.至于何为面向对象,在此就不详说了.面向对象程序设计本身就很值得深入学习,如要了解,请 ...

  6. Python学习笔记之selenium 定制启动 chrome 的选项

    在自动化中,默认情况下我们打开的就是一个普通的纯净的chrome浏览器,而我们平时在使用浏览器时,经常就添加一些插件,扩展,代理之类的应用.所以使用 selenium 时,我们可能需要对 chrome ...

  7. Python学习笔记(一)类和继承的使用

    一年前就打算学Python了,折腾来折腾去也一直没有用熟练,主要是类那一块不熟,昨天用Python写了几个网络编程的示例,感觉一下子迈进了很多.这几天把学习Python的笔记整理一下,内容尽量简洁. ...

  8. python学习道路(day8note)(抽象类,类的方法,异常处理,socket编程)

    1.#面向对象 #抽象接口 === 抽象类 #就是架构师给你一个架子,你们去写,如果满足不了直接报错 #python2 print("python2---抽象类".center(2 ...

  9. python 学习笔记十七 django深入学习二 form,models

    表单 GET 和 POST 处理表单时候只会用到GET 和 POST 方法. Django 的登录表单使用POST 方法,在这个方法中浏览器组合表单数据.对它们进行编码以用于传输.将它们发送到服务器然 ...

随机推荐

  1. wordpress 404 error on all pages!

    You have to enable mod_rewrite in apache itself or you won't be able to have permalinks the way you ...

  2. android快捷简单的实现音乐播放器

    自己做了一个相对完整的音乐播放器,现在把播放模块提取出来,分享给大家.音乐播放器基本功能都实现了的,可能有些BUG,希望谅解. 播放器功能如下: 1.暂停,播放 2.拖动条实现,快进,快退 3.歌词同 ...

  3. 从XML文件乱码问题,探寻其背后的原理

    出现应用程序读取XML文件乱码的场景: 加入xml文件以<?xml version="1.0" encoding="utf-8" ?> 格式的:如果 ...

  4. CSS 有趣的边框

    今天看到一篇文章.是利用CSS边框来做折纸效果.感觉非常有意思.于是就对CSS的border研究了一下.发现还真有一些好玩的使用方法. 1.border折纸效果 首先是HTML代码,为了简单,就一个d ...

  5. 字体图标 icon font

    Icon font icon font 指的是用字体文件代替图片文件,来展示图标.特殊字体等元素的方法. 应用场景: iconfont的优缺点 大小能够自由地变化 颜色能够自由地改动 加入阴影效果 * ...

  6. ListView滑动删除

    本来准备在ListView的每个Item的布局上设置一个隐藏的Button,当滑动的时候显示.但是因为每次只要存在一个Button,发现每个Item上的Button相互间不好控制.所以决定继承List ...

  7. codevs 2541 幂运算(迭代加深搜索)

    /* 一开始想到了简单的深搜 维护当前可用的mi数组 然后回溯用哪个 不断更新新产生的mi 这样的问题是 由于mi不断产生 搜索规模扩大 不好 不好 下面是奇丑的WA掉的代码 做个反面教材 */ #i ...

  8. 【开源java游戏框架libgdx专题】-04-接口介绍及生命周期

    在核心项目中包含6大与操作系统交互的接口,每个后端都实现了这6大接口. Application:运行应用程序并通知API的客户端应用程序级别的事件,提供日志记录设施和查询方法,例如,内存使用. Fil ...

  9. 常用布局,div竖直居中

    常用两列布局,多列布局和div竖直居中 body { margin:; padding:; } .w200 { width: 200px; } .mar-left200 { margin-left: ...

  10. Struts2里如何取得request,session,application

    第一种:取得MAP类型的request,session,application在java文件里写 package com.xjtu.st; import java.util.Map; import c ...