python中类的方法
- 类中的方法,其实就是类中的函数,可以分为:实例方法,类方法,静态方法。方法和字段一样,也是属于类的属性,所以也具有运行中修改的特性, 但一般不推荐这样做
在介绍类的方法之前先补充一下类的私有化属性:
以两个下划线开始,就表示私有化的意思:
class Test(object):
def __hello__(self): # 一个类似魔术方法,并不是私有化
return ' hello welcome'
def __good(self): # 私有方法
return 'good luck'
a = Test()
print a.__hello__() # 魔法方法可以直接访问
print a.__good() # 私有方法不能直接访问
脚本运行效果:
hello welcome #只能访问类似魔术方法
Traceback (most recent call last):
File "/root/PycharmProjects/Pycharm07/lianxi.py", line 184, in <module>
print a.__good() # 私有方法不能直接访问
AttributeError: 'Test' object has no attribute '__good'
可以进行强制访问操作:
a = Test()
print a.__hello__()
print a._Test__good() # 强制访问
再次运行脚本:
hello welcome
good luck # 使用强制访问操作后,就可以访问了
私有方法也可以在类的内部访问,和私有字段一样。
属性的私有化都是对访问入口进行混淆,不建议强制访问私有属性。
实例方法:
- 实例方法需要至少一个默认参数 self
在 init 构造器中,实例方法的特点就是:
- 1.方法的第一个参数必须是 self,这不是固定的,也可以将 self 换成其他如test之类的,但为了别人能看得懂,所以统一使用 self,这里的 self 代表实例本身,也就是说如果实例化时使用的是: a = Test() ,那么 self 就代表 a 这个实例,我们可以在很多构造器中看到类似 self.hello = ‘good’ 的写法,其实这个写法和在类外面 a.hello = ‘good’ 效果是一样的,是为了添加属性。
2.实例方法在调用的时候,self 是自动传递的
3.实例方法一般要有实例才能调用,也可用特殊的调用方法
class Test(object):
def __init__(self, a, b): # 构造器在实例创建时进行属性的初始化
self.a = a
self.b = b
def abc(self, c): # 实例方法
self.c = c
print self.a + self.b + self.c # 因为self是自动传递的,所以我们可以在实例方法中调用实例的属性
a = Test(10, 20) #我们只要为 a 和 b 传参就行了
a.abc(30) #同样的,只要为 c 传参
运行效果:
/usr/bin/python2.7 /root/PycharmProjects/Pycharm07/lianxi.py
60
类方法:
- 第一个参数是cls(类本身);这里通过装饰器和内置函数classmethod实现;
- 类方法在哪个类里面,cls就是谁
- 类方法需要至少一个默认参数 cls
class Test(object):
@classmethod
def abc(cls):
print cls.__name__ # 打印类名
a = Test()
Test.abc() # 类能调用
a.abc() # 实例也能调用
脚本执行效果:
/usr/bin/python2.7 /root/PycharmProjects/Pycharm07/lianxi.py
Test
Test
静态方法:
- 第一个参数既不是self也不是cls;通过装饰器和内置函数staticmethod实现;
- 静态方法不需要默认参数
- 需要注意的是,虽然静态方法没有默认参数, 但并不代表不能有参数
class Test(object):
@staticmethod
def xyz(a, b):
print a + b
Test.xyz(2, 2) # 类调用
a = Test()
a.xyz(3, 6) # 实例调用
脚本执行效果:
/usr/bin/python2.7 /root/PycharmProjects/Pycharm07/lianxi.py
4
9
用方法冒充字段:
- 使用内置函数property,这里用装饰器来实现将方法伪装成字段,在经典类和新式类中分别实现:
class Pager: #经典类
def __init__(self,request_page):
self.request_page = request_page
self.per_items = 10
@property
def start(self):
val = ((self.request_page -1) * self.per_items)+1
return val
@property
def end(self):
val =self.request_page * self.per_items
return val
p = Pager(1)
print p.start # 这里不用加()括号了
print p.end
脚本执行效果:
/usr/bin/python2.7 /root/PycharmProjects/Pycharm07/lianxi.py
1
10
新式类第一种方法:使用装饰器
class Goods(object): #新式类
def __init__(self):
self.old_price = 100
self.discount = 0.7
@property
def price(self):
new_price = self.old_price * self.discount
return new_price
@price.setter
def price(self, value):
self.old_price = value
@price.deleter
def price(self):
del self.old_price
x = Goods()
print x.price
x.price = 160
print x.price
del x.price
print x.price
脚本执行效果:
最后面报错是因为在打印之前执行了del self.old_price
动作 已经将数据删除
/usr/bin/python2.7 /root/Pycharm·Projects/Pycharm07/lianxi.py
70.0
112.0
Traceback (most recent call last):
File "/root/PycharmProjects/Pycharm07/lianxi.py", line 124, in <module>
print x.price
File "/root/PycharmProjects/Pycharm07/lianxi.py", line 107, in price
new_price = self.old_price * self.discount
AttributeError: 'Goods' object has no attribute 'old_price'
第二种方法:不使用装饰器
class Goods(object):
def __init__(self):
self.old_price = 100
self.discount = 0.7
def get_price(self):
new_price = self.old_price * self.discount
return new_price
def set_price(self,value):
self.old_price = value
def del_price(self):
del self.old_price
price = property(get_price, set_price, del_price)
k = Goods()
print k.price
k.price = 180
print k.price
脚本执行效果:
/usr/bin/python2.7 /root/PycharmProjects/Pycharm07/lianxi.py
70.0
126.0
关于类的方法就介绍这些