python特殊函数

    在日常使用python时,我们经常会碰到一些特殊的函数,下面就此进行一定的总结:

1.匿名函数
匿名函数:函数名字被隐藏

匿名函数的定义语法:
lambda 参数1,参数2,...,参数n:函数体

注意:匿名函数函数体只有一行代码,并且该行代码必须具有运行结果,运行结果会被作为函数的返回值自动返回(也可以实现只输出功能,但违背了Python简化代码的初衷,一般不建议使用)
匿名函数因为没有函数名,因此通常是通过变量接受该函数,之后通过变量名(参数列表)来调用。同时匿名函数因为代码只有一句,因此匿名函数一般只用来解决比较简单的数据计算问题
 

##2.递归函数
如果一个函数直接或间接的调用本身,这个函数即为递归函数

注意:正确的递归函数都是有限定值的,即有递归次数的限制,不会无限递归下去。因此正确的递归函数需要设置结束位置

 

##3.闭包函数
闭包函数:在A函数内部定义另外一个函数B,之后B作为A函数的返回值直接被返回,此时函数B称为函数A的闭包函数。

在闭包函数中如果使用了A函数中定义的变量,此时A函数中被定义的变量会被临时存储,直到B函数调用结束时,变量才会被系统回收,从而延长A中变量释放的时间

global:声明的变量属于全局变量,此时在使用该变量时,计算机直接到函数的最外层寻找是否存在该变量

nonlocal:声明的变量属于非本地变量,此时计算机不会在当前变量使用的函数中寻找该变量,而是到该函数的最外层寻找该距离函数比较近的对应变量进行应用
 

# 延续num的寿命
def put(num):
    print(num)
    def wrapper():
        nonlocal num # 非本地变量
        num = num + 20
        print(num)
    return wrapper
fun = put(20)
# 此时put()函数已结束,但num仍存在
fun()
# 20
# 40

 

##4.装饰器
装饰器:装饰器的作用是,通过@语法直接用定义好的函数修饰之前已经存在的函数,从而实现对原函数功能的扩充

装饰器的优点
1.不需要修改原函数代码,即可实现对原函数功能的扩充
2.利于后期代码的维护

# 定义一个带参数的装饰器
import time
import functools
def log(txt):
    def decorator(fun):
        @functools.wraps(fun)
        # 使用functools中函数将fun函数参数的名字赋值给warpper 等价于wrapper.__name__ = fun.__name__
        def wrapper(*args, **kwargs):
            print(txt, end=" ")
            print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))
            return fun(*args, **kwargs)
        return wrapper
    return decorator

# 功能1:求最大值
@log("您当前正在运行的函数运行的时间是")
def max_num(num1, num2):
    print(max(num1, num2))
# 功能2:求最小值
@log("您当前正在运行的函数运行的时间是")
def min_num(num1, num2):
    print(min(num1, num2))
max_num(10, 20)
min_num(10, 20)
# 您当前正在运行的函数运行的时间是2018-07-28 16:03:41
# 20
# 您当前正在运行的函数运行的时间是 2018-07-28 16:10:42
# 10

 

#5.偏函数
偏函数:将指定的函数和函数中默认的参数进行绑定,生成一个新的函数,比如把int函数和int的默认参数base绑定生成一个新的函数int2,int2此时进行数据转化时按照二进制数据进行转化

import functools
int2 = functools.partial(int, base=2)
print(int2("1000"))
# 8

 

6、类的小函数

(1)isinstance:检查是不是这个对象产生的实例,返回布尔值   isinstance(a,b)

(2)issubclass:检查一个类是否是另一个类的子类,返回布尔值 如上


魔法函数:形如__xx__的函数即为魔法函数

(3)__init__    初始化函数(构造函数)

Python的类中可以有很多个构造函数,但是最后一个构造函数会覆盖掉上面的构造函数,所以,只有最后一个init函数有效。

__new__是一个静态函数,并且至少需要传递一个参数cls。cls表示需要实例化的类。此参数在实例化时由Python解释器自动提供。另外,实例化对象时,__new__在__init__方法之前调用。有个比较形象化的比喻:__new__方法就是前期的原材料购买环节,__init__方法就是在有原材料的基础上,加工、初始化商品环节。

class Demo(object): 
  def __init__(self): 
    print('__init__() called...')

  def __new__(cls, *args, **kwargs): 
    print('__new__() - {cls}'.format(cls=cls) )
    return object.__new__(cls, *args, **kwargs) 

if __name__ == '__main__': 
  de = Demo()


输出结果为:
__new__() - <class '__main__.Demo'>
__init__() called...

利用__new__函数可以实现一个简单的单例模式


补:

我们在查看一些项目时,常会发现一个__init__.py文件,

  • __init__.py的在文件夹中,可以使文件夹变为一个python模块,python的每个模块对应的包中都有一个__init__.py文件的存在
  • 通常__init__.py文件为空,但是我们还可以为它增加其他的功能,我们在导入一个模块时候(也叫包),实际上导入的是这个模块的__init__.py文件。我们可以在__init__.py导入我们需要的模块,不需要一个个导入
  • _init__.py 中还有一个重要的变量,叫做 __all__。我们有时会使出一招“全部导入”,也就是这样:from PackageName import *,这时 import 就会把注册在包 __init__.py 文件中 __all__ 列表中的子模块和子包导入到当前作用域中来。比如:#文件 __init__.py中__all__ = ["Module1", "Module2", "subPackage1", "subPackage2"]

(4)__doc__    文档,也就是获取类的注释文档

注意它只返回第一个三对单引号或三对双引号的类的注释文档。

 

(5)__dict__:

以字典的形式返回类的属性及其值,属性和值构成键值对。

如果是 对象.__dict__ 的话返回的是属性和值的字典

如果是 类.__dict__ 的话返回的是类中所有的内容,包括属性、方法

甚至注释文档等。

(6)__call__

实例化对象()自动调用类中的__call__方法,如果类中没有__call__函数的话,实例化对象()这样使用会报错

(7)__str__ 和 __repr__

其实简单来说

__str__是给人看的

__repr__是给机器看的,但是总的来说repr的优先级比str要高,因为str只能给人看,而repr既能给机器看也能给人看。

所以平时尽可能的使用repr。

》示例1

###case 1
class person:
    def __init__(self,fname,lname):
        self.fname=fname
        self.lname=lname

p=person("san","zhang")
print(p)  ###得到一个实例对象及地址
p  ###得到是一个实例对象及地址

###case 2
class person:
    def __init__(self,fname,lname):
        self.fname=fname
        self.lname=lname
    
    def __str__(self):
        return "fnmae:%s,lname:%s"%(self.fname,self.lname)
    
    def __repr__(self):
        return "fnmae:%s,lname:%s"%(self.fname,self.lname)

p=person("san","zhang")
print(p)  ###由于__str__函数,正常显示
p  ###由于__repr__函数,正常显示

》示例2

》示例3:常用魔法函数:

class DictDemo:
    def __init__(self,key,value):
        self.dict = {}
        self.dict[key] = value
    def __getitem__(self,key):
        print("2222")
        return self.dict[key]
    def __setitem__(self,key,value):
        print("3333")
        self.dict[key] = value
    def __len__(self):
        print("4444")
        return len(self.dict)
dictDemo = DictDemo('key0','value0')
print(dictDemo['key0']) #value0
dictDemo['key1'] = 'value1'
print(dictDemo['key1']) #value1
print(len(dictDemo)) #2

######与c不同,python在声明一个类的对象的同时,可以对对象直接进行一些操作,然后自动调用类内的魔法函数。

 

参考链接:

https://blog.csdn.net/w18211679321/article/details/81262221(Python基础之特殊函数类型)

https://blog.csdn.net/ziteng_du/article/details/78825913(Python基础13——python和类相关的几个函数及几个特殊函数)

https://www.cnblogs.com/jiameng991010/p/11257918.htmlPython学习8——魔法方法、特性和迭代器

https://www.cnblogs.com/xie-y/p/8744133.html魔法方法、特性和迭代器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaomu_347

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值