标签:
1、单下划线:开始的成员变量叫 保护变量(protected) 只有类对象和子类对象自己能访问到这些变量
双下划线:开始的是 私有成员(private) 只有类对象自己能访问,连子类对象也不能访问
注:以单下划线开头(_foo)的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用“from xxx import *”而导入;以双下划线开头的(__foo)代表类的私有成员;以双下划线开头和结尾的(__foo__)代表python里特殊方法专用的标识,如 __init__()代表类的构造函数。
2、__slots__
正常情况下,定义一个class,创建一个class的实例后,可以给该实例绑定任何属性和方法,这就是动态语言的灵活性
class Student(object):
pass
然后,尝试给实例绑定一个属性:
s=Student()
s.name=‘zhu‘
print s.name zhu
尝试给实例绑定一个方法:
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
但是给一个实例绑定的方法,对另一个实例是不起作用的,为了给所有实例绑定方法,可以给类class绑定方法:
def set_score(self,score):
self.score=score
Student.set_score=MethodType(set_score,None,Student) 给类绑定一个方法
所以class绑定方法后,所有实例都可以调用
s.set_score(100) 则s.score=100
s2=set_score(99) 则s2.score=99
思考:上面例子中,完全可以把set_score方法直接定义在class中,单动态绑定允许我们在程序运行的过程中动态给class加上功能;这在静态语言中很难实现
如果想要限制class的属性,只允许Student实例添加name和age属性???
为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制class能添加的属性
注:__slots__定义的属性仅对当前类起作用,对继承的子类时不起作用的;除非在子类中也定义__slots__
,这样,子类允许定义的属性就是自身的__slots__
加上父类的__slots__
。
class Student(object):
__slots__=(‘name‘,‘age‘) 用tuple定义允许绑定属性名称
s=Student()
s.age=25
s.name=‘zhu‘
s.score=99 报AttributeError错误
3、@property:python内置的,负责把一个方法变成属性调用
在绑定属性时,我们直接把属性暴露出去,虽然写起来简单,但是没有检查参数,导致成绩随便改
s=Student()
s.score=999
这显然不和逻辑,为了限制score的范围,通过set_score()方法设置成绩,set_score()来获取成绩,这样在set_score()方法中就可以检查参数了:
使用@property
@property广泛用在类的定义中,可以让调用者写出减短的代码,同时保证对参数进行必要的检查,这样程序在运行时就减少了出错的可能性
4、多重继承;;Mixin的目的是给一个类增加多个功能;由于Python允许使用多重继承,因此,Mixin就是一种常见的设计
5、定制类:python的class中还有许多这样有特殊用途的函数,可以帮助我们定制类
①__str__
class Student(object):
... def __init__(self, name):
... self.name = name
... def __str__(self):
... return ‘Student object (name: %s)‘ % self.name
print Student(‘Michael‘)
Student object (name: Michael)
若没有__str__()函数则打印结果是:<__main__.Student object at 0x109afb190>
若直接敲变量s还是>>>s=Student(‘Micheal’)
>>>s 则<__main__.Student object at 0x109afb190>
,这是因为直接显示变量调用的不是__str__(),而是__repr__()
两者区别:__str__() :返回用户看到的字符串
__repr__() :返回程序开发者看到的字符串,就是为调试用的
def __str__(self):
... return ‘Student object (name: %s)‘ % self.name
__repr__=__str__
这样直接单调用实例s时,>>>s 则Micheal
②__iter__
如果一个类想被用于for ... in
循环,类似list或tuple那样,就必须实现一个__iter__()
方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()
方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。
以斐波那契数列为例,写一个Fib类,可以作用于for循环:
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 # 返回下一个值
现在,试试把Fib实例作用于for循环:
>>> for n in Fib():
... print n
...
1
1
2
3
标签:
原文地址:http://www.cnblogs.com/zzfighting/p/5532298.html