函数
参数
形式参数和实际参数
形式参数:定义函数时的参数,是用来接收参数用的,在函数内部作为变量使用
实际参数:调用函数时的参数,是用来把数据传递到函数内部用的
形式参数变量和对象引用的传递
形式参数变量:接收实际参数的变量
对象引用的传递:把实际参数的引用传递给形式参数变量
在python中,所有的参数都是以对象的引用传递的
-
不可变对象:数字、字符串、元组;如果在函数内部修改了参数的值,那么就会在函数内部创建一个新的对象,而不会影响到外部的对象
-
可变对象:列表、字典;如果在函数内部修改了参数的值,那么就会在函数内部修改原来的对象,而不会创建一个新的对象
可选参数
可选参数:在调用函数时,可以不传递的参数
def func(a, b, c=10):
print(a, b, c)
位置参数和命名参数
位置参数:按照位置顺序传递的参数
命名参数:按照参数名传递的参数
def func(a, b, c=10):
print(a, b, c)
func(1, 2, 3) # 1 2 3
func(1, 2) # 1 2 10
func(1, 2, c=3) # 1 2 3
func(1, c=3, b=2) # 1 2 3
可变参数
可变参数:可以接收任意多个参数
- *param:接收任意多个位置参数,会把这些参数当作一个元组传递给形式参数变量
- **param:接收任意多个命名参数,会把这些参数当作一个字典传递给形式参数变量
def func(*args):
print(args)
func(1, 2, 3) # (1, 2, 3)
func(1, 2, 3, 4) # (1, 2, 3, 4)
def func(a, b, **args):
print(a, b, args)
func(1, 2, c=3, d=4) # 1 2 {'c': 3, 'd': 4}
强制命名参数
强制命名参数:必须使用命名参数传递的参数
在形式参数列表中,*
后面的参数都是强制命名参数
def func(*, a, b):
print(a, b)
func(1, 2) # TypeError: func() takes 0 positional arguments but 2 were given
func(a=1, b=2) # 1 2
函数
Lambda表达式
lambda arguments: expression
:创建一个匿名函数,格式为lambda 参数列表: 返回值
func = lambda x: x ** 2
print(func(2)) # 4
函数装饰器Decorator
函数装饰器:用于在不修改原函数的情况下,为原函数添加新的功能
def decorator(func):
def wrapper():
print('before')
func()
print('after')
return wrapper
@decorator
def func():
print('func')
func() # before func after
面向对象
类和对象
类:用来描述具有相同属性和方法的对象的集合
对象:类的实例
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def say(self):
print('My name is {}, I am {} years old.'.format(self.name, self.age))
p = Person('Tom', 18)
p.say() # My name is Tom, I am 18 years old.
属性
属性:类中定义的变量
- 实例属性:通过实例对象添加的属性,只能通过实例对象访问
- 类属性:通过类对象添加的属性,可以通过类对象和实例对象访问
class Person:
name = 'Tom' # 类属性
def __init__(self, age):
self.age = age # 实例属性
- 私有属性:以两个下划线开头的属性,只能在类内部访问
- 共有属性:可以在类内部和外部访问
class Person:
__name = 'Tom' # 私有属性
def __init__(self, age):
self.age = age # 共有属性
- @property装饰器:将一个方法变成属性调用
class Person:
def __init__(self, age):
self.age = age
@property
def age(self):
return self.__age
@age.setter
def age(self, age):
if age < 0:
age = 0
self.__age = age
p = Person(18)
print(p.age) # 18
p.age = -1
print(p.age) # 0
方法
方法:类中定义的函数
- 静态方法:使用
@staticmethod
装饰器修饰的方法,可以通过类对象和实例对象调用,静态方法中不需要传递类对象或实例对象
class Person:
@staticmethod
def func():
print('func')
Person.func() # func
- 类方法:使用
@classmethod
装饰器修饰的方法,可以通过类对象和实例对象调用,类方法中需要传递类对象
class Person:
@classmethod
def func(cls):
print(cls)
Person.func() # <class '__main__.Person'>
- 构造方法:使用
__init__
方法创建对象时会自动调用的方法,用来初始化对象
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
- 析构方法:使用
__del__
方法销毁对象时会自动调用的方法,用来释放对象占用的资源
class Person:
def __del__(self):
print('del')
__call__
方法:使得对象可以像函数一样调用
class Person:
def __call__(self):
print('call')
p = Person()
p() # call
对象的复制
- 引用:两个变量指向同一个对象,通过一个变量修改对象,另一个变量也会受到影响
- 浅复制:复制对象,但是对象中的引用还是指向同一个对象
- 深复制:复制对象,对象中的引用也会复制
import copy
class Person:
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
p1 = Person('Tom', 18,{ 'English': 100, 'Math': 100 })
p2 = p1 # 引用
p3 = copy.copy(p1) # 浅复制
p4 = copy.deepcopy(p1) # 深复制
p1.name = 'Jack'
print(p2.name) # Jack
print(p3.name) # Tom
print(p4.name) # Tom
p1.score['English'] = 90
print(p2.score['English']) # 90
print(p3.score['English']) # 90
print(p4.score['English']) # 100
继承
继承:子类继承父类的属性和方法
派生类:子类,python支持多继承
声明类时,必须在其构造方法的参数列表中调用父类的构造方法,否则会报错
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def say(self):
print('My name is {}, I am {} years old.'.format(self.name, self.age))
class Student(Person):
def __init__(self, name, age, score):
super().__init__(name, age)
self.score = score
def say(self):
super().say()
print('My score is {}.'.format(self.score))
s = Student('Tom', 18, 100)
s.say() # My name is Tom, I am 18 years old. My score is 100.
重载
重载:在同一个类中,方法名相同,参数列表不同的方法
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def say(self):
print('My name is {}, I am {} years old.'.format(self.name, self.age))
def say(self, score):
print('My name is {}, I am {} years old, my score is {}.'.format(self.name, self.age, score))
p = Person('Tom', 18)
p.say(100) # My name is Tom, I am 18 years old, my score is 100.
运算符重载
运算符重载:对内置的运算符进行重载,使其可以作用于自定义的对象上
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __add__(self, other):
return self.age + other.age
p1 = Person('Tom', 18)
p2 = Person('Jack', 20)
ages = p1+p2
print(ages) #38
functools.total_ordering装饰器
functools.total_ordering
装饰器:可以通过重写__eq__
和__lt__
方法,自动重写其他比较方法
需要重写
__eq__
、__lt__
、__gt__
、__le__
、__ge__
中的一个或多个
from functools import total_ordering
@total_ordering
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
return self.age == other.age
def __lt__(self, other):
return self.age < other.age
p1 = Person('Tom', 18)
p2 = Person('Jack', 20)
print(p1 == p2) # False
print(p1 < p2) # True