本文是廖雪峰教程学习记录,廖雪峰链接:http://blog.csdn.NET/GarfieldEr007/article/details/52422494?locationNum=1&fps=1
一、面向对象编程
Object Oriented Programming,OOP。
eg:
>>> class Student(object):#括号里表示Student是从哪个类继承来的,所有类最终继承的是object类
... def __init__(self, name, score):
... self.name=name
... self.score=score
... def print_score(self):
... print '%s: %s' % (self.name, self.score)
...
>>> bart=Student('AA', 80)
>>> lisa=Student('BB', 90)
>>> bart.print_score()
AA: 80
>>> lisa.print_score()
BB: 90
>>> bart._score
80
要让内部属性不能被外部访问,可在属性名字前加两个下划线__,就变成了私有变量,只有内部可以访问,外部不能访问。(若是只有一个下划线,则还可被外部访问,但约定为私有)
将上面例子改一下为:
self.__name = name
self.__score = score
改后无法从外部访问实例变量.__name和实例变量.__score
>>>AA=Student('AA Zhang', 80)
>>> bart.__score
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__score'
外部代码若要获取私有变量,可以给Student类增加获取私有变量的方法
def get_name(self):
return self.__name
若要允许修改私有变量,可给类增加修改私有变量的函数
def set_score(self,score):
self.__score=score
勿用!!双下划线开头的变量实际上也可以从外部访问,有的Python解释器把__name改成了_Student__name
>>> AA._Student__score
79
继承和多态
、获取对象类型
>>> type('123')
<type 'str'>
>>> type(123)
<type 'int'>
>>> isinstance(u'a', basestring)
True
二、dir()
dir()可获得一个对象的所有属性和方法,返回这些属性的list。
>>> dir('ABC')
['__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__', '__siz
eof__', '__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']
>>> 'ABC'.__len__()
3
>>> class MyObject(object):
... def __len__(self): #自己写的类也可以定义__len__属性
... return 100
... def __init__(self):
... self.x=9
... def power(self):
... return self.x * self.x
...
>>> obj = MyObject()
>>> len(obj)
100
hasattr、getattr、setattr等对属性的操作
>>> hasattr(obj, 'x')
True
>>> hasattr(obj, 'y')
False
>>> setattr(obj, 'y', 19)
>>> hasattr(obj, 'y')
True
>>> getattr(obj, 'y')
19
>>>obj.y
19
>>> hasattr(obj, 'z')
False
>>> getattr(obj, 'z', 404) #传入default参数,属性不存在则返回该默认值
404
三、面向对象高级编程
(一) 动态地给实例、或class绑定属性和方法
可定义一个class,创建一个class的实例,再给实例绑定属性和方法。
>>> class Student(object):
... pass
...
>>> s=Student()
>>> s.name = 'Zhang' #动态地给实例绑定属性
>>> print s.name
Zhang
>>> 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_age(self,age):
... self.age = age
...
>>> Student.set_age = MethodType(set_age, None, Student)#给class绑定方法
>>> s.set_age(12)
>>> s.age
12
>>> s2.set_age(100)
>>> s2.age
100
(二)__slots__
若要限制class的属性,如只允许给Student实例增加name和age属性,可在定义class的时候,定义一个特殊的__slots__变量,来限制class能添加的属性:
>>> class Student(object):
... __slots__ = ('name', 'age') #用tuple定义允许的属性
...
>>> s=Student()
>>> s.name='bb'
>>> s.aa='bb'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'aa'
注意:__slots__限制的属性只对当前类起作用,对继承的子类不起作用。
(三)@ property
Python内置 的 @property 装饰器就是负责把一个方法变成属性调用的:
比如对类Student中的属性__score,set_score可设置学生成绩,get_score可获得学生成绩,但这样比较复杂。
class Student(object):
@property
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
>>> import a
>>> s=a.Student()
>>> s.score = 60
>>> s.score
60
>>> s.score = 1001
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "a.py", line 70, in score
raise ValueError('score must between 0~100!')
ValueError: score must between 0~100!
加上@property把getattr方法变成属性,@property本身又创建了另一个装饰器@score.setter,又把另一个方法setattr变成了属性。
只定义getattr,不定义setattr,就是定义了一个只读属性。
(四)多重继承
四、定制类