目录
python从小白到总裁完整教程目录:https://blog.csdn.net/weixin_67859959/article/details/129328397?spm=1001.2014.3001.5502
❤ 类的高级函数
今天来为大家介绍几个类中的高级函数,它们也是类中的内置函数。通过使用它们, 会让我们在进行类开发的时候更加的顺手,接下来我们就看看是哪些函数,让我们一个个的认识它们。
❤ __str__
不知道大家再写程序是,打印一个实例化对象时,打印的其实时一个对象的地址。而通过__str__()函数就可以帮助我们打印对象中具体的属性值,或者你想得到的东西。
因为在python中调用print()打印实例化对象时会调用__str__(),如果__str__()中有返回值,就会打印其中的返回值。
class ss:
def __init__(self,age,name):
self.age = age
self.name = name
def __str__(self):
return str(self.age)+",,wozenmezhemeshuai,,"+self.name
if __name__=="__main__":
s = ss(21,'aitebao')
print(s)
输出结果:
21,,wozenmezhemeshuai,,aitebao
❤ __getattr__
__getattr__
使用:获取属性的时候,如果该属性存在就输出其值,如果不存在则会去找_getatrr_,我们可以通过重写该方法可以实现动态属性的操作。(如果只允许添加指定的属性需要用__solts__限制动态添加变量,这里不做详细讲解)
from requests_html import HTMLSession
class UrlGenerator(object):
def __init__(self, root_url):
self.url = root_url
self.session=HTMLSession()
def __getattr__(self, item):
if item == 'get':
self.get_html()
return UrlGenerator('{}.{}'.format(self.url, item))
def get_html(self):
req = self.session.get(self.url)
print(req.text)
url_gen = UrlGenerator('https://www')
url_gen.baidu.com.get
充分利用__getattr__会在没有查找到相应实例属性时被调用的特点,方便的通过链式调用生成对应的url,在碰到get方法的时候调用函数获取其网页源码。
可调用的对象更加的优雅,链式的操作不仅优雅而且还能很好的说明调用的接口的意义。
下面展示一个__getattr__经典应用的例子,可以通过获取属性值的方式获取字典的键值。
class ObjectDict(dict):
def __init__(self, *args, **kwargs):
super(ObjectDict, self).__init__(*args, **kwargs)
def __getattr__(self, name):
value = self[name]
if isinstance(value, dict):
value = ObjectDict(value)
return value
if __name__ == '__main__':
od = ObjectDict(asf={'a': 1}, d=True)
print(od.asf,od.asf.a) # {'a': 1} 1
print(od.d) # True
❤ __setattr__
__getattr__(用法性质一样)和__setattr__用来对属性的设置和取值进行处理
class Book(object):
def __setattr__(self, name, value):
if name == 'value':
object.__setattr__(self, name, value - 100)
else:
object.__setattr__(self, name, value)
def __getattr__(self, name):
try:
return object.__getattribute__(name)
except:
return name + ' is not found!'
def __str__(self):
return self.name + ' cost : ' + str(self.value)
c = Book()
c.name = 'Python'
c.value = 100
print c.name
print c.value
print c
print c.Type
上面的例子中,在赋值书的value属性时,偷偷的将value减去了100。输出结果:
Python
0
Python cost : 0
Type is not found!
❤ __call__
在Python中,函数其实是一个对象:
>>> f = abs
>>> f.__name__
'abs'
>>> f(-123)
123
由于 f 可以被调用,所以,f 被称为可调用对象
所有的函数都是可调用对象
一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法__call__()
我们把 Person 类变成一个可调用对象:
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def __call__(self, friend):
print 'My name is %s...' % self.name
print 'My friend is %s...' % friend
现在可以对 Person 实例直接调用:
>>> p = Person('Bob', 'male')
>>> p('Tim')
My name is Bob...
My friend is Tim...
单看 p('Tim') 你无法确定 p 是一个函数还是一个类实例,所以,在Python中,函数也是对象,对象和函数的区别并不显著。
任务
改进一下前面定义的斐波那契数列:
class Fib(object):
???
请加一个__call__方法,让调用更简单:
>>> f = Fib()
>>> print f(10)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
可以把实例对象用类似函数的形式表示,进一步模糊了函数和对象之间的概念
class Fib(object):
def __init__(self):
pass
def __call__(self,num):
a,b = 0,1;
self.l=[]
for i in range (num):
self.l.append(a)
a,b= b,a+b
return self.l
def __str__(self):
return str(self.l)
__rept__=__str__
f = Fib()
print f(10)
输出:
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]