一,面向对象编程

1,类和实例,

class Student(object):#括号里面的是继承的类
def __init__(self, name, score):初始化对象时,参数个数
self.name = name
self.score = score
def print_score(self):
print '%s: %s' % (self.name, self.score)

2,访问限制

1,如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__

2,但是如果外部代码要获取name和score怎么办?可以给Student类增加get_nameget_score这样的方法,,好处:可以对参数做检查,避免传入无效的参数:

lass Student(object):
def __init__(self, name, score):
self.__name = name #双下划线,外部无法直接访问
self.__score = score
def print_score(self):
print '%s: %s' % (self.__name, self.__score)
def set_score(self, score): #通过set_来做筛选
if 0 <= score <= 100:
self.__score = score
else:
raise ValueError('bad score')
def get_name(self): #通过get_来获取参数
return self.__name def get_score(self):
return self.__score

3,继承和多态

1,继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写;默认继承object

2,有了继承,才能有多态。在调用类实例方法的时候,尽量把变量视作父类类型,这样,所有子类类型都可以正常被接收;如猫,狗等都属于动物,即为一种多态表现

4,获取对象信息

1,type方法;

>>> import types
>>> type(int)==types.TypeType
True
>>> type(int)
<type 'type'>
>>> type(int)==type(str)
True

2,isinstance()方法:>>> isinstance('abc',str)   True

3,dir():获取对象所有方法和属性

>>> dir('o1')
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

(二),面向对象编程

1,绑定

对象和类动态绑定属性和方法:

>>> class Student(object):
... pass
...
>>> s = Student()
>>> s.name = 'Michael' # 动态给实例绑定一个属性
>>> print s.name
Michael
>>> def set_age(self, age): # 定义一个函数作为实例方法
... self.age = age
...
>>> from types import MethodType
>>> s.set_age = MethodType(set_age, s, Student) # 给实例绑定一个方法
>>> s.set_age(25) # 调用实例方法
>>> s.age # 测试结果
25
>>> def set_score(self, score):
... self.score = score
...
>>> Student.set_score = MethodType(set_score, None, Student)
>>> s.set_score(100)
>>> s.score
100
>>> s2.set_score(99)
>>> s2.score
99
# 关键方法MethodTypes(方法名,对象(所有为None),类名)

2,限制

  但是,如果我们想要限制class的属性怎么办?比如,只允许对Student实例(而非对象)添加nameage属性。

  除非在子类中也定义__slots__,这样,子类允许定义的属性就是自身的__slots__加上父类的__slots__

>>> class Student(object):
... __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
...
>>> class GraduateStudent(Student):#新建子类,子类可以为继承父类的__slots__
# 除非在子类中也定义__slots__,这样,子类允许定义的属性就是自身的__slots__加上父类的__slots__。 如添加__slots__=('sex'),即子类被限制为name,age,sex了
... pass
...
>>> g = GraduateStudent()
>>> g.score = 9999

3,@property

作用:既能检查参数,又可以用类似属性这样简单的方式来访问类的变量,即对参数二次开发。

class Student(object):
@property #相当于 score.getter 表示读
def score(self):
return self._score @score.setter #对属性进行先验,附加条件 表示写
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
>>> s = Student()
>>> s.set_score(60) # ok!
>>> s.get_score()
60
>>> s.set_score(9999) #get raise异常
Traceback (most recent call last):
...
ValueError: score must between 0 ~ 100!

4,多重继承

继承的方法按照深度优先的情况选择:如

class Grandfa(object):
def hair(self):
print 'no hair' class Father(Grandfa):
pass class Mother(Grandfa):
def hair(self):
print 'long hair' class Tom(Father,Mother):
pass me = Tom()
me.hair()
# 输出long hair

关系从上到下为:object→Grandfa→father  and  mother →Tom:深度优先遍历顺序为:Tom→father(没有hair方法)→mother(有hair方法,返回值,遍历结束) 相当于先左子树,再右子树,最后父类寻找方式。

5,定制类

1,__str__和__repr__():两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,__repr__()是为调试服务的。

>>> class student(object):
... def __str__(self):
... return 'is str'
... def __repr__(self):
... return 'is repr'
...
>>> s=student()
>>> s
is repr
>>> print s
is str
# 通常__str__()和__repr__()代码都是一样的

2,__iter__:如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环

  __getitem__:可以按下标获取指定值,或可以向集合一样切片

class Fib(object):
def __init__(self):
self.a, self.b = 0, 1 # 初始化两个计数器a,b
def __iter__(self):
return self # 实例本身就是迭代对象,故返回自己
def next(self):
self.a, self.b = self.b, self.a + self.b # 计算下一个值
if self.a > 100000: # 退出循环的条件
raise StopIteration();
return self.a # 返回下一个值
>>> for n in Fib():
... print n
...
class Fib(object):
def __getitem__(self, n):
if isinstance(n, int):
a, b = 1, 1
for x in range(n):
a, b = b, a + b
return a
if isinstance(n, slice):
start = n.start
stop = n.stop
a, b = 1, 1
L = []
for x in range(stop):
if x >= start:
L.append(a)
a, b = b, a + b
return L
>>> f = Fib()
>>> f[0:5]
[1, 1, 2, 3, 5]

3,__getattr__:防止正常情况下,当我们调用类的方法或属性时,如果不存在,就会报错的情况,

4,__call__:任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用。__call__()还可以定义参数,判断一个对象是否能被调用。

class Student(object):
def __init__(self, name):
self.name = name def __call__(self):
print('My name is %s.' % self.name)
>>> s = Student('Michael')
>>> s()
My name is Michael.
>>> callable(max)
True #能被调用
>>> callable([1, 2, 3])
False #不能被调用

6,使用元类

:不会碰到需要使用metaclass的情况,暂不了解

(三) 错误调试

1,错误处理

try...except...finally...:finally重会执行:但是finally如果有,则一定会被执行(可以没有finally语句)

raise:raise语句抛出一个错误的实例,print异常,代价大,增加吞吐量,所以用raise抛出即可

抛出异常:如果程序中出现了异常,没有办法将具体的异常打印出来,不做任何处理

捕获异常:如果程序出现了异常,就能够详细的打印是什么原因导致了异常并且能够做出相应的处理,能够显示详细的Log

logging:出错,但程序打印完错误信息后会继续执行,并正常退出。

try:
foo()
except StandardError, e:
print 'StandardError'
except ValueError, e:
print 'ValueError'
# StandardError是ValueError,的父类,所以第二个except永远也捕获不到,子类要重写父类中的方法,如果父类的方法有异常声明,子类异常小于等于父类异常

2,调试

1,assert  断言 来辅助查看的地方

# err.py
def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n def main():
foo('')
#
$ python err.py
Traceback (most recent call last):
...
AssertionError: n is zero!
#关闭assert python -O err.py, 按默认情况抛异常

2,logging    日志相关操作

import logging
logging.basicConfig(level=logging.INFO)#它允许你指定记录信息的级别,有debug,info,warning,error等几个级别
s=''
n=int(s)
logging.info('n =%d' %n)
print 10/n
#通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件。

3,单元测试

单元测试可以有效地测试某个程序模块的行为,是未来重构代码的信心保证。

单元测试的测试用例要覆盖常用的输入组合、边界条件和异常。

单元测试代码要非常简单,如果测试代码太复杂,那么测试代码本身就可能有bug。

单元测试通过了并不意味着程序就没有bug了,但是不通过程序肯定有bug。

#测试功能
class Dict(dict): def __init__(self, **kw):
super(Dict, self).__init__(**kw) def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(r"'Dict' object has no attribute '%s'" % key) def __setattr__(self, key, value):
self[key] = value
#测试函数
import unittest from mydict import Dict class TestDict(unittest.TestCase): def test_init(self):
d = Dict(a=1, b='test')
self.assertEquals(d.a, 1)
self.assertEquals(d.b, 'test')
self.assertTrue(isinstance(d, dict)) def test_key(self):
d = Dict()
d['key'] = 'value'
self.assertEquals(d.key, 'value') def test_attr(self):
d = Dict()
d.key = 'value'
self.assertTrue('key' in d)
self.assertEquals(d['key'], 'value') def test_keyerror(self):
d = Dict()
with self.assertRaises(KeyError):
value = d['empty'] def test_attrerror(self):
d = Dict()
with self.assertRaises(AttributeError):
value = d.empty if __name__ == '__main__':
unittest.main()
# 测试原理还是不太清楚,以后有需要再去了解下
python -m unittest mydict_test
.....
----------------------------------------------------------------------
Ran 5 tests in 0.000s OK

4,文档测试

doctest非常有用,不但可以用来测试,还可以直接作为示例代码。通过某些文档生成工具,就可以自动把包含doctest的注释提取出来。用户看文档的时候,同时也看到了doctest。

class Dict(dict):
'''
Simple dict but also support access as x.y style. >>> d1 = Dict()
>>> d1['x'] = 100
>>> d1.x
100
>>> d1.y = 200
>>> d1['y']
200
>>> d2 = Dict(a=1, b=2, c='3')
>>> d2.c
'3'
>>> d2['empty']
Traceback (most recent call last):
...
KeyError: 'empty'
>>> d2.empty
Traceback (most recent call last):
...
AttributeError: 'Dict' object has no attribute 'empty'
''' def __init__(self, **kw):
super(Dict, self).__init__(**kw) def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(r"'Dict' object has no attribute '%s'" % key) def __setattr__(self, key, value):
self[key] = value if __name__=='__main__':
import doctest
doctest.testmod()
# python Dict.py 没结果输出,表示运行正常。

最新文章

  1. 分享一个LiteDB做的简单考试系统辅助工具
  2. Links for Introduction To Calculus
  3. vs2010 和vs2012的区别 副标题--Loaded事件走两次
  4. Centos7 Cacti-0.8.8g安装及SNMP简介
  5. ABAP SY-SUBRC 使用过程中返回值的几种含义
  6. 基础学习day02--标识符、关键字、数据类型与运算符
  7. SQLITE LIMIT
  8. IOS基础——alloc、init和new方法
  9. ???????????? no permissions
  10. Docker和DevOps是找工作必备技能
  11. 实现能够直接粘QQ贴截图的bug管理功能
  12. Use View.isInEditMode() in your custom views to skip code when shown in Eclipse
  13. Spring MVC (JDK8+Tomcat8)
  14. bzoj 2288 【POJ Challenge】生日礼物 双向链表+堆优化
  15. Windows XP Mode安装
  16. mongoose多条件模糊查询实例
  17. js中树结构根据条件查找节点返回节点路径的一些思路
  18. 恢复oracle数据从delete
  19. JavaScript 运行机制详解
  20. 详解重定向(HTTP状态码301/302/303/307/408)附例子

热门文章

  1. The UVALIVE 7716 二维区间第k小
  2. BZOJ1233 [Usaco2009Open]干草堆tower 【单调队列优化dp】
  3. 文件搜索工具everything
  4. Access数据库 INSERT INTO 失败
  5. ubuntu安装mysql报错
  6. 转 Scrapy笔记(5)- Item详解
  7. HTML添加上传图片并进行预览
  8. 漂亮的弹窗口插件——sweetAlert的使用
  9. SenseTime Ace Coder Challenge 暨 商汤在线编程挑战赛*
  10. 扩展欧拉定理【p4139】上帝与集合的正确用法