help()是Python中的内置函数,可以查询Python中函数的用法。
help(print)
文档字符串就是函数的说明,在定义函数时,可以在函数内部编写文档字符串,可以通过help()函数来查看函数的说明,其实就是在函数的第一行写一个字符串。
1.形参后面加:表示形参指定的类型。
2.函数后面加->表示该函数的返回值。
def fn(a:int,b:bool) -> int:
'''
:param a: int
:param b: bool
:return: int
'''
return 1
help(fn)
作用域指的就是变量生效的区域。在Python中有两种作用域,分别是全局作用域和函数作用域。
1.全局作用域在程序执行时创建,在程序执行结束时销毁。
2.所有函数以外的区域都是全局作用域。
3.在全局作用域中定义的变量都属于全局变量,可以在程序的任意位置被访问。
1.函数作用域在函数调用时创建,在调用结束时销毁。
2.函数每调用一次就会产生一个新的函数作用域。
3.在函数作用域中定义的变量都是局部变量,只能在函数内部被访问。
1.当使用变量时,会优先在当前作用域中查找该变量,如果有则使用,如果没有则继续去上一级作用域中查找,以此类推,如果查找到全局作用域依然没有,则会抛出异常。
2.在函数中为变量赋值时,默认都是为局部变量赋值,如果需要在函数内部修改全局变量,则需要使用global关键字来声明变量,此时修改的就是全局变量。
a = 10
def fn():
global a
a += 10
print(a)
fn()
1.命名空间实际上是一个专门用来存储变量的字典,可以使用locals()获取当前作用域的命名空间。如果在全局作用域中调用locals()则获取全局命名空间,如果在函数作用域中调用locals()则获取函数命名空间,其返回值是一个字典。
2.globals()函数可以用来在任意位置获取全局命名空间。
简单理解就是函数自己调用自己。递归是解决问题的一种方式,整体思想是将一个大问题分解成若干小问题,直到问题无法分解时再去解决问题。
递归的两个条件:
1.基线条件:问题被分解成最小问题,当满足基线条件时,递归就不再执行。
2.递归条件:将问题继续分解的条件。
创建一个函数,可以用来求任意数的阶乘。
def factorial(n):
'''
该函数用来求任意数的阶乘
:param n: int
:return: result
'''
if n == 1:
return 1
if n > 1:
return (n * factorial(n - 1))
print(factorial(10))
创建一个函数,检查指定的字符串是否是回文字符串。
def hui_wen(s):
'''
该函数用来检查指定的字符串是否是回文字符串,如果是返回True,如果不是返回False
:param s: 要检查的字符串
:return: True or False
'''
length = len(s)
if length < 2:
return True
elif s[0] != s[-1]:
return False
return hui_wen(s[1:-1])
print(hui_wen('abcba'))
在Python中,函数是一等对象。一等对象一般都会具有如下特点:
1.对象是在运行时创建的。
2.能赋值给变量或作为数据结构中的元素。
3.能作为参数传递。
4.能作为返回值返回。
高阶函数指的是接收函数作为参数或者将函数作为返回值的函数,其至少要符合以下两个特点中的一个:
1.接收一个或多个函数作为参数。
2.将函数作为返回值返回。
接收函数作为参数。
filter()函数可以从序列中过滤出符合条件的元素,保存到一个新的序列中。
其参数有函数(根据该函数来过滤序列)和需要过滤的序列,其返回值是过滤后的新序列。
filter(fn1,l)
lambda函数表达式专门用来创建一些简单的函数,是函数创建的一种方式,匿名函数一般都是作为参数使用,其语法是:
lambda 参数列表:返回值
def fn(a,b):
return a + b
lambda a,b:a + b
map()函数可以对可迭代对象中所有元素做指定操作,然后将其添加到一个新的对象中返回。
l = [1,2,3,4,5]
r = map(lambda i : i + 1,l)
print(list(r))
sort()方法用来对列表中的元素进行排序。其默认是直接比较列表中元素的大小,在sort()可以接收一个关键字参数key,key需要一个函数作为参数。当设置了函数作为参数,每次都会以列表中的一个元素作为参数来调用函数,并且使用函数的返回值来比较元素的大小。
l = ['aa','b','cccc','ddd']
l.sort(key=len)
print(l)
sorted()函数的用法和sort()基本一致,但是sorted()可以对任意的序列进行排序,并且不会影响到原来的对象,而是返回一个新对象。
l = '11467892346802348'
print(sorted(l,key=int))
print(l)
将函数作为返回值返回,这种高阶函数称为闭包,通过闭包可以创建一些只有当前函数能访问的变量,可以将一些私有数据隐藏在闭包中。
def fn():
a = 10
def fn1():
print('fn1函数',a)
return fn1
"""
r是一个调用fn()后返回的函数。因为该函数在fn()内部被定义,所以该函数总是能够访问到fn()函数内部的变量"""
r = fn()
r()
形成闭包的条件:
1.函数嵌套
2.将内部函数作为返回值返回
3.内部函数必须要使用到外部函数的变量
def make_average():
nums = []
def average(n):
nums.append(n)
return sum(nums) / len(nums)
return average
averager = make_average()
print(averager(20))
通过装饰器,可以在不修改原来函数的情况下来对函数进行扩展,在开发中,都是通过装饰器来扩展函数的功能。在定义函数时,可以通过@装饰器来使用指定的装饰器用来装饰当前的函数,可以同时为一个函数指定多个装饰器,这样函数将会按照从内向外的顺序被装饰。
Python是一门面向对象的编程语言,面向对象语言中的所有操作都是通过对象来进行的。面向对象的编程语言关注的是对象而不是过程。面向对象的编程思想将所有的功能统一保存到对应的对象中,要使用某个功能,直接找到对应的对象即可。这种方式编写的代码比较容易阅读,并且比较易于维护,容易复用。
简单理解类就相当于对象的图纸,在程序中需要根据类来创建对象,也成对象是类的实例(instance),如果多个对象是通过一个类创建的,则称这些对象是一类对象。
自定义的类都需要使用大写字母开头,使用大驼峰命名法来对类进行命名。
class MyClass():
pass
mc = MyClass() # mc就是通过MyClass创建的对象,mc是MyClass的实例
result = isinstance(mc,MyClass) # 用来检查一个对象是否是一个类的实例,如果是返回True,否则返回False
1.创建一个变量
2.在内存中创建一个新对象
3.init方法执行
4.将对象的id赋值给变量
class MyClass():
pass
mc = MyClass()
此时通过MyClass这个类创建的对象是一个空对象,可以向对象中添加变量,对象中的变量称为属性。语法是:
对象.属性名 = 属性值
类和对象都是对现实生活中的事物或程序中内容的抽象。
在类的代码块中,可以定义变量和函数,其会成为所有实例的公共属性,所有实例都可以访问这些变量(对象.属性名)。在类中也可以定义函数,类中定义的函数称为方法,这些方法可以通过该类的所有实例来访问(对象.方法名())。
调用函数时传递几个参数,就会有几个实参,方法调用时,默认会传递一个参数,所以方法中至少要定义一个形参。
当调用一个对象的属性时,解析器会先在当前对象中寻找是否含有该属性。如果有,则直接返回当前的对象的属性值,如果没有,则去当前对象的类对象中寻找,如果有则返回类对象的属性值,如果没有则报错。
如果这个属性或方法是所有的实例共享的,则应将其保存到类对象中;如果这个属性或方法是某个实例独有的,则应该保存到实例对象中。一般情况下,属性保存到实例对象中,而方法需要保存到类对象中。
方法每次被调用时,解析器都会自动传递第一个实参,就是调用方法的对象本身,一般会将这个参数命名为self。
在类中可以定义一些特殊方法,特殊方法将会在特殊的时刻自动调用。
init()会在对象创建以后立即执行,可以用来新创建的对象中初始化属性。调用类创建对象时,类后边的所有参数都会依次传递到init()中。
class 类名([父类]):
公共的属性
# 对象的初始化方法
def _init_(self,...):
...
# 其他的方法
def method_1(self,...):
...
class Dog:
def __init__(self,name,age,gender,height):
self.name = name
self.age = age
self.gender = gender
self.height = height
def jiao(self):
print('%s 叫'%self.name)
def yao(self):
print('%s 咬'%self.name)
def run(self):
print('%s 跑'%self.name)
d = Dog('小黑',10,'男',20)
print(d.name,d.age,d.gender,d.height)
d.jiao()
d.yao()
d.run()
封装指的是隐藏对象中一些不希望被外部所访问到的属性或方法。将对象的属性名修改为一个外部不知道的名字即可隐藏该属性。在外部可以使用getter(get_属性名)和setter(set_属性名)方法来获取和设置对象中指定属性。
使用封装增加了类的定义的复杂程度,但是确保了数据的安全性,其隐藏了属性名,使调用者无法随意修改对象中的属性,增加了getter和setter方法,很好的控制了属性是否是只读的。
如果希望属性可读,则可以直接去掉setter方法,如果希望属性不能被外部访问,则可以直接去掉getter方法。
1.使用setter方法设置属性,可以增加数据的验证,确保数据的值是正确的。
2.使用getter方法获取属性,使用setter方法设置属性,可以在读取和修改属性的同时做一些其他的处理。
class Dog:
'''
表示狗的类
'''
def __init__(self,name,age):
self.hidden_name = name
self.hidden_age = age
def say_hello(self):
print('大家好,我是%s' %self.hidden_name)
def get_name(self):
print('用户读取了属性')
return self.hidden_name
def set_name(self):
print('用户修改了属性')
self.hidden_name = name
def get_age(self):
return self.hidden_age
def set_age(self,age):
if age > 0:
self.hidden_age = age
else:
print('输入的年龄不合法')
可以为对象的属性使用双下划线开头,__xxx,双下划线开头的属性是对象的隐藏属性,只能在类的内部访问,无法通过对象访问。使用双下划线开头的属性,实际上依然可以在外部访问,所以这种方式一般不使用。一般会将一些私有属性(不希望被外部访问的属性)以下划线开头。
一般情况下,使用下划线开头的属性都是私有属性,没有特殊需要不要修改私有属性。
property装饰器用来将一个get方法转换为对象的属性,添加为property装饰器后,可以像调用属性一样使用get方法。使用property装饰的方法,其方法名必须和属性名一致。
@属性名.setter是setter方法的装饰器
class Person:
def __init__(self,name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name = name