递归 && 反射

函数的产生可以使代码可以重复使用。

递归的产生可以 使函数重复使用自己,但是python默认递归的深度为1000,这个深度是可以修改的。

自己理解:递归虽然可以重复使用但是,需要设置一个条件,这个条件就是使递归跳出循环的。

def age(n):
    if n == 1:
        return 40
    return age(n-1)+2

 递归进行二分查找:

def find(lst,aim):  #这种算法可以在查找的值存在的情况下,不会报错,但是在,查找不    存在的值时,就会报错。
    mid = len(lst)//2
    if aim > lst[mid]:
        find(lst[mid+1:],aim)
    elif aim < lst[mid]:
        find(lst[:mid],aim)
    else:print(aim,mid)
find(ls,66)    
#现在的方法可以解决,查找如果不存在的值不报错
def find(lst,aim):
    mid = len(lst)//2
    if mid:
        if aim > lst[mid]:
            find(lst[mid+1:],aim)
        elif aim < lst[mid]:
            find(lst[:mid],aim)
        else:print(aim,mid)
    else:print("你查找的值不存在")
find(ls,66)
View Code

 如何在二分查找的时候知道索引值

函数参数,如果在不确定用户是否传值的情况下,可以使用默认参数,None

递归时,列表,所以要先判断 开始值小于结束值

递归进阶:

  需要在原装饰器的基础上增加一个函数,为了把函数传进去。目的是为了装饰器内部使用一定的外部条件,带参数的装饰器。

  两种方式:返回装饰器内部的值:第一种:全局变量,第二种:写入到文件里   第三种:写入到数据库

  同一个函数被两个装饰器装饰:先执行第一个装饰器的第一个语句,然后执行第二个装饰器的全部。

  

def wrapper1(func):
    def inner1(*args,**kwargs):
        print('in wrapper 1,before')
        ret = func(*args,**kwargs)   #qqxing
        print('in wrapper 1,after')
        return ret
    return inner1

def wrapper2(func):     #inner1
    def inner2(*args,**kwargs):
        print('in wrapper 2,before')
        ret = func(*args,**kwargs)   #inner1
        print('in wrapper 2,after')
        return ret
    return inner2

@wrapper2 #wrapper2 = wrapper2(inner1)
@wrapper1
def qqxing():   #qqxing = @wrapper1(qqxing)
    print('qqxing')

qqxing()    #inner2
View Code

 递归的特性

 递归的最大深度——997

def foo(n):
    print(n)
    n += 1
    foo(n)
foo(1)
测试最大递归深度

由此我们可以看出,未报错之前能看到的最大数字就是997.当然了,997是python为了我们程序的内存优化所设定的一个默认值,我们当然还可以通过一些手段去修改它:

import sys
print(sys.setrecursionlimit(100000))
修改递归最大深度

三级菜单使用递归实现

menu = {
    '北京': {
        '海淀': {
            '五道口': {
                'soho': {},
                '网易': {},
                'google': {}
            },
            '中关村': {
                '爱奇艺': {},
                '汽车之家': {},
                'youku': {},
            },
            '上地': {
                '百度': {},
            },
        },
        '昌平': {
            '沙河': {
                '老男孩': {},
                '北航': {},
            },
            '天通苑': {},
            '回龙观': {},
        },
        '朝阳': {},
        '东城': {},
    },
    '上海': {
        '闵行': {
            "人民广场": {
                '炸鸡店': {}
            }
        },
        '闸北': {
            '火车战': {
                '携程': {}
            }
        },
        '浦东': {},
    },
    '山东': {},
}

menu
menu

l = [menu]
while l:
    for key in l[-1]:print(key)
    k = input('input>>').strip()   # 北京
    if k in l[-1].keys() and l[-1][k]:l.append(l[-1][k])
    elif k == 'b':l.pop()
    elif k == 'q':break
堆栈实现

递归函数与二分查找算法

l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
如果这样,假如我要找的数比列表中间的数还大,是不是我直接在列表的后半边找就行了?

简单版二分法

l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]

def func(l,aim):
    mid = (len(l)-1)//2
    if l:
        if aim > l[mid]:
            func(l[mid+1:],aim)
        elif aim < l[mid]:
            func(l[:mid],aim)
        elif aim == l[mid]:
            print("bingo",mid)
    else:
        print('找不到')
func(l,66)
func(l,6)
二分法基础版

升级版二分法

def search(num,l,start=None,end=None):
    start = start if start else 0
    end = end if end else len(l) - 1
    mid = (end - start)//2 + start
    if start > end:
        return None
    elif l[mid] > num :
        return search(num,l,start,mid-1)
    elif l[mid] < num:
        return search(num,l,mid+1,end)
    elif l[mid] == num:
        return mid
二分算法终极版

 反射

什么是反射

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

反射原理

通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

四个可以实现自省的函数

下列方法适用于类和对象(一切皆对象,类本身也是一个对象

hasattr、getattr、setattr、delattr

class Foo:
    f = '类的静态变量'
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def say_hi(self):
        print('hi,%s'%self.name)

obj=Foo('egon',73)

#检测是否含有某属性
print(hasattr(obj,'name'))
print(hasattr(obj,'say_hi'))

#获取属性
n=getattr(obj,'name')
print(n)
func=getattr(obj,'say_hi')
func()

print(getattr(obj,'aaaaaaaa','不存在啊')) #报错

#设置属性
setattr(obj,'sb',True)
setattr(obj,'show_name',lambda self:self.name+'sb')
print(obj.__dict__)
print(obj.show_name(obj))

#删除属性
delattr(obj,'age')
delattr(obj,'show_name')
delattr(obj,'show_name111')#不存在,则报错

print(obj.__dict__)
四个方法的使用演示
class Foo(object):
 
    staticField = "old boy"
 
    def __init__(self):
        self.name = 'wupeiqi'
 
    def func(self):
        return 'func'
 
    @staticmethod
    def bar():
        return 'bar'
 
print getattr(Foo, 'staticField')
print getattr(Foo, 'func')
print getattr(Foo, 'bar')
类也是对象
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import sys


def s1():
    print 's1'


def s2():
    print 's2'


this_module = sys.modules[__name__]

hasattr(this_module, 's1')
getattr(this_module, 's2')
反射当前模块成员

导入其他模块,利用反射查找该模块是否存在某个方法

#!/usr/bin/env python
# -*- coding:utf-8 -*-

def test():
    print('from the test')
View Code
#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
"""
程序目录:
    module_test.py
    index.py
 
当前文件:
    index.py
"""

import module_test as obj

#obj.test()

print(hasattr(obj,'test'))

getattr(obj,'test')()
View Code
原文地址:https://www.cnblogs.com/huyangblog/p/7805059.html