Python调用其他文件中的函数如何调用特殊函数

扫一扫体验手机阅读
python特殊函数之lambda和map
<span type="1" blog_id="1676389" userid='
45篇文章,6W+人气,0粉丝
大数据时代的微服务之路
¥51.00495人订阅Python学习笔记——特殊方法
特殊方法定义在class内
不需要直接调用
Python的某些函数或操作附会调用对应的特殊方法
__str__和 __repr__
python把任意变量变成str,因为任意数据类型的实例都有一个特殊方法 __str__()
__str__()用于显示给用户,而__repr__()用于显示给开发人员。
__repr__的目标是准确性,%r打印时能够重现它所代表的对象
__str__的目标是可读性,%s
import datetime
d = datetime.date.today()
print "%s" % d
print "%r" % d
datetime.date()
对 int、str 等内置数据类型排序时,Python的 sorted() 按照默认的比较函数 cmp 排序,但是,如果对一组类的实例排序时,就必须提供我们自己的特殊方法 __cmp__()
sorted默认由小到大,cmp()
sorted(iterable, cmp=None, key=None, reverse=False)
类实现了__cmp__()方法,__cmp__用实例自身self和传入的实例 s 进行比较,如果 self 应该排在前面,就返回 -1,如果 s 应该排在前面,就返回1,如果两者相当,返回 0
修改 Student 的 __cmp__ 方法,让它按照分数从高到底排序,分数相同的按名字排序
class Student(object):
def __init__(self,name,score):
self.name = name
self.score = score
def __str__(self):
return '(%s:%s)' % (self.name,self.score)
def __cmp__(self,s):
if self.score == s.score:
return cmp(self.name,s.name)
return -cmp(self.score,s.score)
L = [Student('Tim',79),Student('Bob',82),Student('Tom',99)]
print sorted(L)
如果一个类表现得像一个list,要获取有多少个元素,就得用 len() 函数。类必须提供一个特殊方法__len__(),它返回元素的个数。
打印斐波那契数列,并返回数列和个数
class Fib(object):
def __init__(self,num):
a,b,L = 0,1,[]
for i in range(10):
L.append(a)
a,b = b,a+b
self.num = L
def __str__(self):
return str(self.num)
__repr__ = __str__
def __len__(self):
return len(self.num)
f = Fib(10)
print len(f)
用于有理数的运算
def gcd(a,b):
if b == 0:
return gcd(b,a%b)
class Rational(object):
def __init__(self,p,q):
self.p = p
self.q = q
def __add__(self,r):
return Rational(self.p*r.q+self.q*r.p,self.q*r.q)
def __sub__(self,r):
return Rational(self.p*r.q-self.q*r.p,self.q*r.q)
def __mul__(self,r):
return Rational(self.p*r.p,self.q*r.q)
def __div__(self,r):
return Rational(self.p*r.q,self.q*r.p)
def __str__(self):
g = gcd(self.p,self.q)
return '%s/%s' % (self.p/g,self.q/g)
__repr__ = __str__
r1 = Rational(1,2)
r2 = Rational(1,4)
print r1 + r2
print r1 - r2
print r1 * r2
print r1 / r2
用装饰器(@property)函数把 get/set 方法“装饰”成属性调用
@property—这是关键字,固定格式,能让方法当“属性”用。
@score.setter—前面的”score”是@property紧跟的下面定义的那个方法的名字,”setter”是关键字,这种“@+方法名字+点+setter”是个固定格式与@property搭配使用。
class Student(object):
def __init__(self,name,score):
self.name = name
self.__score = score
def score(self):
return self.__score
@score.setter
def score(self,score):
if score & 0 or score & 100:
raise ValueError('invalid score')
self.__score = score
def grade(self):
if self.__score & 60:
return 'C'
if self.__score & 80:
return 'B'
return 'A'
s = Student('Tom',80)
print s.grade
s.score = 62
print s.grade
s.score = 98
print s.grade
由于Python是动态语言,任何实例在运行期都可以动态地添加属性。
如果要限制添加的属性,例如,Student类只允许添加 name、gender和score 这3个属性,就可以利用Python的一个特殊的__slots__来实现。
顾名思义,__slots__是指一个类允许的属性列表
class Student(object):
__slots__=('name','gender','score')
def __init__(self,name,gender,score):
self.name = name
self.score = score
self.gender = gender
__slots__的目的是限制当前类所能拥有的属性,如果不需要添加任意动态的属性,使用__slots__也能节省内存。
在Python中,函数其实是一个对象.所有的函数都是可调用对象。一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法__call__()。
class Fib(object):
def __call__(self,num):
a,b,L = 0,1,[]
for n in range(num):
L.append(a)
a,b = b,a+b
print f(10)
python中数学运算
TensorFlow 学习积累(2): Python类中的__init__() 和 self
Python中class的内置函数__str__
python核心编程学习笔记--01-左加法__add__和右加法__radd__
python类的内置方法一
python __add__和__radd__
python内置方法之完整版
Python __str__(self)和__unicode__(self)
python: 理解__str__
Python的特殊方法
没有更多推荐了,Python——函数
def sum_2_num():
result = num1 + num2
print("%d + %d = %d" % (num1, num2, result))
print(num1,num2)
sum_2_num()
def sum_3_num(num1, num2):
result = num1 + num2
print("%d + %d = %d" % (num1, num2, result))
sum_3_num(50, 20)
def sum_4_num(num1, num2):
对两个数字的求和
return num1 + num2
# 调用函数,并使用 result 变量接收计算结果
result = sum_4_num(10, 20)
print("计算结果是 %d" % result)
# def print_line(char):
print(char * 50)
# print_line(6)
def print_line(char, times):
print(char * times)
def print_lines(char, times):
while row & 5:
print_line(char, times)
print_line(10,20)
没有更多推荐了,python中实现定制类的特殊方法总结
转载 &更新时间:日 09:44:47 & 作者:wuhn
这篇文章主要介绍了python中实现定制类的特殊方法总结,本文讲解了__str__、__iter__、__getitem__、__getattr__、__call__等特殊方法,需要的朋友可以参考下
看到类似__slots__这种形如__xxx__的变量或者函数名就要注意,这些在Python中是有特殊用途的。
__slots__我们已经知道怎么用了,__len__()方法我们也知道是为了能让class作用于len()函数。
除此之外,Python的class中还有许多这样有特殊用途的函数,可以帮助我们定制类。
我们先定义一个Student类,打印一个实例:
&&& class Student(object):
...&&&& def __init__(self, name):
...&&&&&&&& self.name = name
&&& print Student('Michael')
&__main__.Student object at 0x109afb190&
打印出一堆&__main__.Student object at 0x109afb190&,不好看。
怎么才能打印得好看呢?只需要定义好__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)
这样打印出来的实例,不但好看,而且容易看出实例内部重要的数据。
但是细心的朋友会发现直接敲变量不用print,打印出来的实例还是不好看:
&&& s = Student('Michael')
&__main__.Student object at 0x109afb310&
这是因为直接显示变量调用的不是__str__(),而是__repr__(),两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,__repr__()是为调试服务的。
解决办法是再定义一个__repr__()。但是通常__str__()和__repr__()代码都是一样的,所以,有个偷懒的写法:
class Student(object):
&&& def __init__(self, name):
&&&&&&& self.name = name
&&& def __str__(self):
&&&&&&& return 'Student object (name=%s)' % self.name
&&& __repr__ = __str__
如果一个类想被用于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
__getitem__
Fib实例虽然能作用于for循环,看起来和list有点像,但是,把它当成list来使用还是不行,比如,取第5个元素:
&&& Fib()[5]
Traceback (most recent call last):
& File "&stdin&", line 1, in &module&
TypeError: 'Fib' object does not support indexing
要表现得像list那样按照下标取出元素,需要实现__getitem__()方法:
class Fib(object):
&&& def __getitem__(self, n):
&&&&&&& a, b = 1, 1
&&&&&&& for x in range(n):
&&&&&&&&&&& a, b = b, a + b
&&&&&&& return a
现在,就可以按下标访问数列的任意一项了:
&&& f = Fib()
&&& f[100]
但是list有个神奇的切片方法:
&&& range(100)[5:10]
[5, 6, 7, 8, 9]
对于Fib却报错。原因是__getitem__()传入的参数可能是一个int,也可能是一个切片对象slice,所以要做判断:
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
现在试试Fib的切片:
&&& f = Fib()
&&& f[0:5]
[1, 1, 2, 3, 5]
&&& f[:10]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
但是没有对step参数作处理:
&&& f[:10:2]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
也没有对负数作处理,所以,要正确实现一个__getitem__()还是有很多工作要做的。
此外,如果把对象看成dict,__getitem__()的参数也可能是一个可以作key的object,例如str。
与之对应的是__setitem__()方法,把对象视作list或dict来对集合赋值。最后,还有一个__delitem__()方法,用于删除某个元素。
总之,通过上面的方法,我们自己定义的类表现得和Python自带的list、tuple、dict没什么区别,这完全归功于动态语言的“鸭子类型”,不需要强制继承某个接口。
__getattr__
正常情况下,当我们调用类的方法或属性时,如果不存在,就会报错。比如定义Student类:
class Student(object):
&&& def __init__(self):
&&&&&&& self.name = 'Michael'
调用name属性,没问题,但是,调用不存在的score属性,就有问题了:
&&& s = Student()
&&& print s.name
&&& print s.score
Traceback (most recent call last):
AttributeError: 'Student' object has no attribute 'score'
错误信息很清楚地告诉我们,没有找到score这个attribute。
要避免这个错误,除了可以加上一个score属性外,Python还有另一个机制,那就是写一个__getattr__()方法,动态返回一个属性。修改如下:
class Student(object):
&&& def __init__(self):
&&&&&&& self.name = 'Michael'
&&& def __getattr__(self, attr):
&&&&&&& if attr=='score':
&&&&&&&&&&& return 99
当调用不存在的属性时,比如score,Python解释器会试图调用__getattr__(self, 'score')来尝试获得属性,这样,我们就有机会返回score的值:
&&& s = Student()
&&& s.name
&&& s.score
返回函数也是完全可以的:
class Student(object):
&&& def __getattr__(self, attr):
&&&&&&& if attr=='age':
&&&&&&&&&&& return lambda: 25
只是调用方式要变为:
&&& s.age()
注意,只有在没有找到属性的情况下,才调用__getattr__,已有的属性,比如name,不会在__getattr__中查找。
此外,注意到任意调用如s.abc都会返回None,这是因为我们定义的__getattr__默认返回就是None。要让class只响应特定的几个属性,我们就要按照约定,抛出AttributeError的错误:
class Student(object):
&&& def __getattr__(self, attr):
&&&&&&& if attr=='age':
&&&&&&&&&&& return lambda: 25
&&&&&&& raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)
这实际上可以把一个类的所有属性和方法调用全部动态化处理了,不需要任何特殊手段。
这种完全动态调用的特性有什么实际作用呢?作用就是,可以针对完全动态的情况作调用。
举个例子:
现在很多网站都搞REST API,比如新浪微博、豆瓣啥的,调用API的URL类似:
如果要写SDK,给每个URL对应的API都写一个方法,那得累死,而且,API一旦改动,SDK也要改。
利用完全动态的__getattr__,我们可以写出一个链式调用:
class Chain(object):
&&& def __init__(self, path=''):
&&&&&&& self._path = path
&&& def __getattr__(self, path):
&&&&&&& return Chain('%s/%s' % (self._path, path))
&&& def __str__(self):
&&&&&&& return self._path
&&& Chain().status.user.timeline.list
'/status/user/timeline/list'
这样,无论API怎么变,SDK都可以根据URL实现完全动态的调用,而且,不随API的增加而改变!
还有些REST API会把参数放到URL中,比如GitHub的API:
GET /users/:user/repos
调用时,需要把:user替换为实际用户名。如果我们能写出这样的链式调用:
Chain().users('michael').repos
就可以非常方便地调用API了。有兴趣的童鞋可以试试写出来。
一个对象实例可以有自己的属性和方法,当我们调用实例方法时,我们用instance.method()来调用。能不能直接在实例本身上调用呢?类似instance()?在Python中,答案是肯定的。
任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用。请看示例:
class Student(object):
&&& def __init__(self, name):
&&&&&&& self.name = name
&&& def __call__(self):
&&&&&&& print('My name is %s.' % self.name)
调用方式如下:
&&& s = Student('Michael')
My name is Michael.
__call__()还可以定义参数。对实例进行直接调用就好比对一个函数进行调用一样,所以你完全可以把对象看成函数,把函数看成对象,因为这两者之间本来就没啥根本的区别。
如果你把对象看成函数,那么函数本身其实也可以在运行期动态创建出来,因为类的实例都是运行期创建出来的,这么一来,我们就模糊了对象和函数的界限。
那么,怎么判断一个变量是对象还是函数呢?其实,更多的时候,我们需要判断一个对象是否能被调用,能被调用的对象就是一个Callable对象,比如函数和我们上面定义的带有__call()__的类实例:
&&& callable(Student())
&&& callable(max)
&&& callable([1, 2, 3])
&&& callable(None)
&&& callable('string')
通过callable()函数,我们就可以判断一个对象是否是“可调用”对象。
Python的class允许定义许多定制方法,可以让我们非常方便地生成特定的类。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具Python中函数的多种格式和使用实例及小技巧
转载 &更新时间:日 08:47:08 & 投稿:junjie
这篇文章主要介绍了Python中函数的多种格式和使用实例及小技巧,本文讲解了普通格式、带收集位置参数的函数、带收集关键字参数的函数、函数特殊用法、内嵌函数和闭包等内容,需要的朋友可以参考下
这里先解释一下几个概念
- 位置参数:按位置设置的参数,隐式用元组保存对应形参.平时我们用的大多数是按位置传参.比如有函数def func(a,b,c),调用func(1,2,3).即a=1,b=2,c=3
- 关键字参数:可以通过关键字设置参数,不用关心参数位置,隐式用字典保存形参.比如有函数def func(a,b,c),调用func(b=1,c=2,a=3),即a=3,b=1,c=2
def func(opt_args):
&&& return value
带收集位置参数的函数
def func(*params):
&&& return value
使用函数时,不用限制传参的个数,*params会自动收集传入的参数作为一个元组.
def& func(*params):
&&& print params
a = [1,2,3,4]
b = 'hello'
func(a, b, c)
([1, 2, 3, 4], ‘hello', 3)
带收集关键字参数的函数
def func(**params):
&&& return value
按关键字传参时,**params会自动收集传入的参数作为一个字典.
def& func(**params):
&&& print params
func(a=1, b=2, c=3)
{‘a': 1, ‘c': 3, ‘b': 2}
函数特殊用法
def func(a = 1, b = 2)
等号(=)号是默认值,调用函数时可以不用传参给默认参数.
def& func(a = 1, b = 2):
&&& print a, b&
函数可以返回多个值
return a, b, c
def& func(a = 1, b = 2):
&&& return a, b
print func(a=3)
内嵌函数和闭包
def foo()&&& #外部函数
&&& def bar()&&& #内嵌函数
&&&&&&& ....
如果内嵌函数引用了外部函数的变量(包括外部函数参数),这个引用的变量称为自由变量, 那么称这个内嵌函数是闭包.再来看看专业的解释:闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。
def foo(a, b):
&&& def bar():
&&&&&&& return x * a +
&&& return bar
f1= foo(1, 2)
f2= foo(2, 3)
print f1(), f2()
Python一切皆对象,函数这一语法结构也是一个对象, 可以将函数名作为参数传递
def bar(*param1, **param2):
def foo(bar, *param1, **param2):
&&& bar(*param1, **param2)
def bar(*param1, **param2):
&&& print param1
&&& print param2
def foo(bar, *param1, **param2):
&&& bar(*param1, **param2)
foo(bar,& 1, 2, 3,& a = 111, b = 222, c = 333)
{‘a': 111, ‘c': 333, ‘b': 222}
匿名函数与lambda
lambda语法可以创建一个匿名的函数,主要作用是简化书写,是一种语法糖.
lambda [arg1[, arg2, … argN]] : expression
def foo(x, y):
&&& return x + y
print& "call foo function, result is: ", foo(3, 4)
bar = lambda x = 2, y = 3 : x + y
print& "call lambda fucntion, result is:", bar(3,4)
call foo function, result is: 7
call lambda fucntion, result is: 7
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具}

我要回帖

更多关于 python绘画图表 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信