递归的终止条件通常定义在递归函数内部,在递归调用前要作一个条件判断,根据判断的结果选择是继续调用自身,仍是return;返回终止递归。
终止的条件:
一、判断递归的次数是否达到某一限定值
二、判断运算的结果是否达到某个范围等,根据设计的目的来选择html
参考地址:https://blog.csdn.net/weixin_43527495/article/details/84841368python
def sum(a,b): c=a+b return c if __name__=="__main__": print(sum(2,4)) a=lambda x,y: x+y print(a(1,2)) #使用匿名函数的实现方法
结果为:6,3git
参考地址:https://www.cnblogs.com/wc554303896/p/7710974.htmlgithub
设计模式是通过总结,优化的,对咱们常常会碰到的一些编程问题的可重用解决方案。一个设计模式并不像一个类或一个库那样可以直接做用于咱们的代码,反之,设计模式更为高级,它是一种必须在特定情形下实现的一种方法模板。 常见的是工厂模式和单例模式数据库
单例模式应用的场景通常发如今如下条件下: 资源共享的状况下,避免因为资源操做时致使的性能或损耗等,如日志文件,应用配置。 控制资源的状况下,方便资源之间的互相通讯。如线程池等,1,网站的计数器 2,应用配置 3.多线程池 4数据库配置 数据库链接池 5.应用程序的日志应用...编程
print([x*x for x in range(1, 11)])
装饰器本质上是一个callable object ,它可让其余函数在不须要作任何代码变更的前提下增长额外功能,装饰器的返回值也是一个函数对象。设计模式
import time from functools import wraps def timeit(func): @wraps(func) def wrapper(*args, **kwargs): start = time.clock() ret = func(*args, **kwargs) end = time.clock() print('used:',end-start) return ret return wrapper @timeit def foo(): print('in foo()'foo())
在函数内部再定义一个函数,而且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包。python3.x
装饰器本质上是一个callable object,它能够在让其余函数在不须要作任何代码的变更的前提下增长额外的功能。装饰器的返回值也是一个函数的对象,它常常用于有切面需求的场景。好比:插入日志,性能测试,事务处理,缓存。权限的校验等场景,有了装饰器就能够抽离出大量的与函数功能自己无关的雷同代码并发并继续使用。缓存
迭代器是遵循迭代协议的对象。用户可使用 iter() 以从任何序列获得迭代器(如 list, tuple, dictionary, set 等)。另外一个方法则是建立一个另外一种形式的迭代器 —— generator 。要获取下一个元素,则使用成员函数 next()(Python 2)或函数 next() function (Python 3) 。当没有元素时,则引起 StopIteration 此例外。若要实现本身的迭代器,则只要实现 next()(Python 2)或 __next__
()( Python 3)网络
生成器(Generator),只是在须要返回数据的时候使用yield语句。每次next()被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置和全部的数据值)
区别: 生成器能作到迭代器能作的全部事,并且由于自动建立iter()和next()方法,生成器显得特别简洁,并且生成器也是高效的,使用生成器表达式取代列表解析能够同时节省内存。除了建立和保存程序状态的自动方法,当发生器终结时,还会自动抛出StopIteration异常。
X= (i for i in range(10)) X是 generator类型
N =100 print ([[x for x in range(1,100)] [i:i+3] for i in range(0,100,3)])
yield就是保存当前程序执行状态。你用for循环的时候,每次取一个元素的时候就会计算一次。用yield的函数叫generator,和iterator同样,它的好处是不用一次计算全部元素,而是用一次算一次,能够节省不少空间,generator每次计算须要上一次计算结果,因此用yield,不然一return,上次计算结果就没了
什么是可变/不可变对象
不可变对象,该对象所指向的内存中的值不能被改变。当改变某个变量时候,因为其所指的值不能被改变,至关于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址。
可变对象,该对象所指向的内存中的值能够被改变。变量(准确的说是引用)改变后,其实是其所指的值直接发生改变,并无发生复制行为,也没有开辟新的出地址,通俗点说就是原地改变。
Python中,数值类型(int
和float
)、字符串str、元组tuple都是不可变类型。而列表list、字典dict、集合set是可变类型。
参考地址:https://www.cnblogs.com/sun-haiyu/p/7096918.html
参考地址:https://blog.csdn.net/qq_38520096/article/details/79237593
只读属性
1.概念:一个属性(通常指实例属性),只能读取,不能写入。
2.应用场景:有些属性,只限在内部根据不一样场景进行修改,而对外界来讲,不能修改,只能读取。
好比:电脑类的网速属性,网络状态属性
3.方式1:方案:所有隐藏(私有化,既不能读,也不能写。),部分公开(公开读的操做)
具体实现:私有化(经过“属性前置双下划线”实现。)部分公开:(经过公开的方法)
class Person: def __init__(self): self.__age = 18 def getAge(self): return self.__age p1 = Person() print(p1.getAge()) p1.__age = 99 print(p1.__age)
优化方案:装饰器@porperty。做用:将一些“属性的操做方法”关联到某一个属性当中。
class Person(object): def __init__(self): self.__age = 18 # 主要做用就是,能够以使用属性的方式,来使用这个方法。 @property def age(self): return self.__age p1 = Person() print(p1.age) p1.age = 1 print(p1.age)
概念补充:经典类:没有继承(object)
新式类:继承(object)
python2.x版本中定义一个类时,默认不继承(object)
python3.x版本中定义一个类时,默认继承(object)
建议使用:新式类
class Person: pass print(Person.__bases__) class Man: pass print(Man.__bases__) # 在python2.x版本中,若是定义一个类。没有显示的继承自object,那么这个类就是一个经典类。必须显示的继承自object,它才是一 # 个新式类 # 在python3.x版本中,若是直接定义一个类,会隐式的继承object,默认状况下,就已是一个新式类。
class Person(object): # def __init__(self): # # self.__age = 18 # def get_age(self): # print("-----, getage") # return self.__age # # def set_age(self, value): # print("-----, setage") # self.__age = value # # age = property(get_age, set_age) # # p = Person() # # print(p.age) # # p.age = 90 # print(p.age) # print(p.__dict__)
5.property在新式类和经典类中的使用方法。
在经典类中使用property方法,只能关联读取方法。不能关联写入、删除这些方法。能写不能用。
#_*_encoding:utf-8_*_ # --------------------------------------------propert在新式类中的两种使用方法------------------------------------------- # property 第一种使用方式 # class Person(object): # def __init__(self): # # self.__age = 18 # def get_age(self): # print("-----, getage") # return self.__age # # def set_age(self, value): # print("-----, setage") # self.__age = value # # age = property(get_age, set_age) # # p = Person() # # print(p.age) # # p.age = 90 # print(p.age) # print(p.__dict__) # property 第二种使用方式 # class Person(object): # def __init__(self): # self.__age = 18 # @property # def age(self): # print("-----, get") # return self.__age # # @age.setter # def age(self, value): # print("-----, set") # self.__age = value # # # p = Person() # print(p.age) # # p.age = 100 # print(p.age) # --------------------------------------------propert在经典类中的两种使用方法------------------------------------------- # property 第在经典类中的第一种使用方式 # class Person(object): # def __init__(self): # self.__age = 18 # # def get_age(self): # print("-----, getage") # return self.__age # # def set_age(self, value): # print("-----, setage") # self.__age = value # # age = property(get_age, set_age) # # p = Person() # # print(p.age) # # p.age = 90 # print(p.age) # print(p.__dict__) # property 第在经典类中的第二种使用方式 class Person(object): def __init__(self): self.__age = 18 @property def age(self): print("-----, get") return self.__age @age.setter def age(self, value): print("-----, set") self.__age = value p = Person() print(p.age) p.age = 100 print(p.age) print(p.__dict__)
6.只读属性设置方式2
class Person(object): # 当咱们经过实例.属性 = 值,给一个实例增长一个属性。或者说,修改一下属性的值的时候,都用调用这个方法。 # 在这个方法内部才会真正的把这个属性以及对应的数据,给存储到__dict__字典里面。 def __setattr__(self, key, value): print(key, value) #1. 断定key是不是咱们要设置的只读属性的名称 if key == "age" and key in self.__dict__.keys(): print("这个属性是只读属性,不能设置数据") #2.若是说不是这个只读属性的名称,真正的添加到这个实例里面去。 else: self.__dict__[key] = value p1 = Person() p1.age = 18 print(p1.age) p1.age = 999 print(p1.age) p1.lala = 100 print(p1.lala) print(p1.__dict__)
参考地址:https://blog.csdn.net/u010962876/article/details/80740578
所谓的面向对象就是将咱们的程序模块化,对象化,把具体事物的特性属性和经过这些属性来实现一些动做的具体方法放到一个类里面,这就是封装。封装是咱们所说的面相对象编程的特征之一。除此以外还有继承和多态。继承有点相似与咱们生物学上的遗传,就是子类的一些特征是来源于父类的,儿子遗传了父亲或母亲的一些性格,或者相貌,又或者是运动天赋。有点种瓜得瓜种豆得豆的意思。面向对象里的继承也就是父类的相关的属性,能够被子类重复使用,子类没必要再在本身的类里面从新定义一回,父类里有点咱们只要拿过来用就行了。而对于本身类里面须要用到的新的属性和方法,子类就能够本身来扩展了。固然,会出现一些特殊状况,就是咱们在有一些方法在父类已经定义好了,可是子类咱们本身再用的时候,发现,其实,咱们的虽然都是计算工资的,可是普通员工的工资计算方法跟经理的计算方法是不同的,因此这个时候,咱们就不能直接调用父类的这个计算工资的方法了。这个时候咱们就须要用到面向对象的另外一个特性,多态。对,就是多态,咱们要在子类里面把父类里面定义计算工资的方法在子类里面从新实现一遍。多态包含了重载和重写。重写很简单就是把子类从父亲类里继承下来的方法从新写一遍,这样,父类里相同的方法就被覆盖了,固然啦,你仍是能够经过super.CaculSalary方法来调用父类的工资计算方法。而重载就是类里面相同方法名,不一样形参的状况,能够是形参类型不一样或者形参个数不一样,或者形参顺序不一样,可是不能使返回值类型不一样。
参考地址:https://blog.csdn.net/xukun5137/article/details/46792287