Python——函数和面向对象

一.函数

函数定义

1.将多行代码放在一起,起个名字称为函数定义

2.函数必须先定义后调用

好处:减少代码的冗余,提高程序的编写效率

语法:

def 函数名():

代码

1. def是关键字,用来定义函数的

2. 函数名需要遵守标识符的规则

3. 处于def缩进中的代码,称为函数体

4. 函数定义的时候,函数体中的代码不会执行,在调用的时候才会执行

函数的调用

使用多行代码的时候,称为函数调用

语法:

函数名()

1.函数调用的时候会执行函数体中的代码

2. 函数调用的代码要写在函数体外

# 1. 编写一个打招呼 say_hello 的函数,封装三行打招呼的代码
# 2. 在函数下方调用打招呼的代码
# 函数的定义,不会执行函数中的代码
def say_hello():
    print('hello 1')
    print('hello 2')
    print('hello 3')
# 想要执行函数中的代码,需要调用
say_hello()

组包和拆包

组包(pack):将多个数据值使用逗号连接,组成元组

拆包(unpack):将容器中的数据值使用多个变量分别保存的过程,注意:变量的个数和容器中数据的个数要保持一致

赋值运算符,都是先执行等号右边的代码,执行的结果,保存到等号左边的变量中

# 组包
a, b = 20, 10
c = b, a  # 组包
print(type(c), c)  # <class 'tuple'> (10, 20)
# 拆包
a, b = c
print(a, b)  # 10 20

全局变量和局部变量

局部变量

在函数中定义的变量,称为局部变量
特点:
1.局部变量只能在当前函数内部使用,不能在其他函数和函数外部使用
2.在不同函数中,可以定义名字相同的局部变量,两者之间没有影响
3.在函数被调用的时候局部变量被创建,函数调用结束,局部变量的值被销毁不能使用
所以函数中的局部变量的值,如果想要在函数外部使用,需要使用return关键字,将这个值返回
def func1():
    num = 10  # num 就是局部变量
    print(f"func1 函数中 {num}")


def func2():
    num = 100  # 可以在不同函数中定义名字相同的局部变量,没有影响
    print(f"func2 函数中 {num}")


func1()  # 10
func2()  # 100
func1()  # 10

全局变量

在函数外部定义的变量,称为全局变量 特点: 1.可以在任何函数中读取全局变量的值 2.如何在函数中存在和全局变量名字相同的局部变量,在函数中使用的是局部变量的值 3.在函数内部想要修改全局变量的引用,添加global关键字,对变量进行声明为全局变量 4.代码执行的时候被创建,代码执行结束被销毁
g_num = 10  # 全局变量
​
​
def func1():
    print(f'func1 中 {g_num}')  # 在函数中可以读取全局变量的值
​
​
def func2():
    g_num = 20  # 定义局部变量, 不会影响全局变量
    print(f'func2 中 {g_num}')
​
​
def func3():
    global g_num  # 这个函数中使用的 g_num  都是全局变量, 写在函数的第一行
    g_num = 30  # 修改了全局变量
    print(f'func3 中 {g_num}')

​
func1()  # 10
func2()  # 20
func1()  # 10
func3()  # 30
func1()  # 30

函数参数

  • 位置传参

函数调用的时候,按照形参的顺序,将实参值传递给形参

  • 关键字传参

函数调用的时候,指定数据值给形参

  • 混合使用

关键字传参必须写在位置传参后面

不要给一个形参传递多个数据值

def func(a, b, c):
    print(f'a: {a}, b: {b}, c: {c}')
​
​
# 位置传参
func(1, 2, 3)
# 关键字传参
func(a=2, b=3, c=1)
# 混合使用
func(1, 3, c=5)

缺省参数

缺省参数,默认参数
列表.pop() #不写参数,删除最后一个
列表.sort(reverse=True)
1.定义方式
在函数定义时候给形参一个默认的数据值,这个形参就变为缺省参数,注意缺省参数的书写要放在普通参数后面
2.特点
雀神参数,在函数调用时候,可以传递实参值,也可以不传递实参值
如果传参使用的就是传递的实参值,如果不传参使用的就是默认值
def show_info(name, sex='保密'):
    print(name, sex)
​
​
show_info('小王')
show_info('小王', '男')

多值参数

  • 不定长位置参数(不定长元组参数)

1.书写,在普通参数的前边,加上一个*, 这个参数就变为不定长位置参数
2.特点,这个形参可以接收任意多个位置传参的数据
3.数据类型,形参的类型是元组
4.注意,不定长位置参数要写在普通的参数的后面
5,一般写法,不定长位置参数的名字为args,即(*args)
  • 不定长关键字参数(不定长字典参数)

1.书写,在普通参数的前边,加上两个*, 这个参数就变为不定长关键字参数
2.特点,这个形参可以接收任意多个关键字传参的数据
3.数据类型,形参的类型是字典
4,注意,不定长关键字参数,要写在所有参数的最后边
5,一般写法,不定长关键字参数的名字为kwargs,即(**kwargs)
  • 完整的参数顺序

def 函数名(普通函数, *args, 缺省参数, **kwargs):
    pass 
​
# 一般在使用的时候, 使用 1-2种, 按照这个顺序挑选书写即可
def func(*args, **kwargs):
    print(type(args), args)
    print(type(kwargs), kwargs)
    print('-' * 30)
​
​
func()
func(1, 2, 3)  # 位置传参, 数据都给 args
func(a=1, b=2, c=3)  # 关键字传参, 数据都给 kwargs
func(1, 2, 3, a=4, b=5, c=6)

匿名函数

匿名函数:就是使用lanbda关键字定义的函数 一般称为使用def 关键字定义的函数为标准函数 匿名函数只能书写⼀⾏代码 匿名函数的返回值不需要return,⼀⾏代码(表达式)的结果就是返回值 使⽤场景:作为函数的参数,这个函数⽐较简单,值使⽤⼀次,没有必要使⽤def定义

语法:

lambda参数: 一行代码 # 这一行代码,称为是表达式
# 匿名函数一般不需要我们主动的调用, 一般作为函数的参数使用的
# 我们在学习阶段为了查看匿名函数定义的是否正确,可以调用
# 1, 在定义的时候 ,将匿名函数的引用保存到一个变量中
变量 = lambda参数: 一行代码
# 2. 使用变量进行调用
变量()
# 无参无返回值  打印输出 hello world
def func1():
    print('hello world')


func1()
# lambda : print('hello world')
func11 = lambda: print('hello lambda')
func11()

二.面向对象

面向对象是一种编程思想

1.面向过程

2.面向对象

以上两种都属于写代码的套路,最终目的都是为了将代码写出来,只不过过程和思想方法不一样

类和对象

抽象的概念, 对 多个 特征和行为相同或者相似事物的统称

泛指的(指代多个,而不是具体的一个)

  • 对象

具体存在的一个事物, 看得见摸得着的

特指的,(指代一个)

类的组成:

1,类名(给这多个事物起一个名字,在代码中满足大驼峰命名法(每个单词的首字母大写))

2,属性(事物的特征,即有什么,一般文字中的名词)

3,方法(事物的行为,即做什么事,一般是动词)

面向对象基本书写

1.定义类

先定义简单的类,不包含属性,在python中定义类需要使用关键字class

⽅法:⽅法的本质是在类中定义的函数,只不过,第⼀个参数是self

class 类名:

# 在缩进中书写的内容,都是类中的代码

def 方法名(self): # 就是一个方法

pass

2.创建对象

创建对象时使用类名()进行创建

类名() #创建⼀个对象,这个对象在后续不能使⽤

#创建的对象想要在后续的代码中继续使⽤,需要使⽤⼀个变量,将这个对象保存起来

变量=类名()

#这个变量中保存的是对象的地址,⼀般可以成为这个变量为对象

#⼀个类可以创建多个对象,只要出现类名()就是创建⼀个对象,每个对象的地址是不⼀样的

3.调用方法

对象.方法名()

例:

列表.sort()

列表.append()

# 1. 创建类
class Person:
    # 定义方法, 在类的缩进中定义的函数就是方法
    def eat(self):  
        print('吃饭...')

    def drink(self):
        print('喝水...')


number1 = Person()
number1.eat()
number1.drink()
self的说明:
1.从函数的语法上讲,self是形参,就可以是任意的变量名,只不过我们习惯性将这个形参写作self
2.self是普通的形参,但是在调⽤的时候没有传递实参值,原因是,Python解释器在执⾏代码的时候,⾃动的将调⽤这个⽅法的对象传递给了self,即self的本质是对象
3.验证,只需要确定通过哪个对象调⽤,对象的引⽤和self的引⽤是⼀样的
4.self是函数中的局部变量,直接创建的对象是全局变量

对象的属性操作

添加属性

对象.属性名 = 属性值
  • 类内部添加

在内部方法中,self是对象
self.属性名 = 属性值
在类中添加属性一般写在_init_方法中
  • 类外部添加

对象.属性名 = 属性值

获取属性

对象.属性名
  • 类内部

在内部方法中,self是对象
self.属性名
  • 类外部

对象.属性名
# 1. 定义类
class Person:
    # 定义方法
    def eat(self):
        print(f'{self.name} 在吃饭')


# 2. 创建对象
tom = Person()
# 添加 name 属性
tom.name = "汤姆"
# 3. 调用方法
tom.eat()

__init__方法

1.什么情况下自动调用
创建对象之后自动调用
2.有什么用,用在哪
1.给对象添加属性的(初始化方法,构造方法)
2.某些代码,在每次创建对象之后,都要执行,就可以将这行代码写在 __init_ _方法(双下划线)
3.书写注意事项
1.如果init方法中存在了self之外的参数,在创建对象的时候必须传参
class Person:
    # 定义添加属性方法
    def __init__(self,name,age):
        self.name = name  # 给对象添加属性
        self.age = age

__str__方法

1.什么情况下自动调用
使用print(对象)打印对象的时候会自动调用
2.有什么用,用在哪
1.在这个方法中一般书写对象的属性信息的,即打印对象的时候要查看什么信息,在这个方法中进行定义的
2.如果类中没有定义__str__方法(双下划线),print(对象),默认输出对象的引用地址
3.书写注意事项
这个方法必须返回一个字符串
class Person:
    # 定义添加属性方法
    def __init__(self,name,age):
        self.name = name  # 给对象添加属性
        self.age = age


    def __str__(self):
        # 方法必须返回的是一个字符串
        return f'名字是{self.name},年龄是{self.age}'

__del__方法

__init__方法创建对象之后会自动调用
__del__方法对象被删除销毁时,自动调用
1.调用场景,程序代码运行结束,所有对象都被销毁
2.调用场景,直接使用del删除对象(如果对象有多个名字(多个对象引用一个对象),需要把所有对象都删除才行)
class Demo:
    def __init__(self, name):
        print('我是 __init__, 我被调用了 ')
        self.name = name
​
    def __del__(self):
        print(f'{self.name} 没了')

​
a = Demo('a')
b = Demo('b')
del a  # 删除销毁 对象,
print('代码运行结束')

私有和公有

class Demo:
    def __init__(self, name, age):
        self.name = name
        # python 私有的本质是 修改属性的名字, 在私有属性名前添加 _类名 前缀
        self.__age = age  # 将 age 属性设置为私有的  # __age --> _Demo__age

    def __str__(self):
        return f"name: {self.name}, age: {self.__age}"  # __age --> _Demo__age


# 创建对象
a = Demo('大黄', 2)
print(a.name)  # name 是公有属性,可以在类外部使用
# print(a.__age)   # __age 是私有属性,不能在类外部使用
a.__age = 10  # 在类外部只能添加和修改公有属性, 添加一个公有属性,名字是 __age
print(a.__age)  # 访问的是公有属性 __age
print(a)  #
print(a._Demo__age)  # 2
a._Demo__age = 3
print(a)

继承

继承描述的是类与类之间的关系
继承的好处:减少代码的冗余(相同的代码不需要多次重复书写),可以直接使用

语法:

#class A(object):

class A: # 没有写父类,但也有父类,object,object类是python中最顶级的类

pass

class B(A): # 类B,继承类A

# 定义一个动物类 Animal类, 方法: 吃
class Animal:
    def eat(self):
        print('饿了要吃东西....')


# 定义一个狗类 Dog类,继承动物类
class Dog(Animal):
    # 在 Dog 类,定义叫的方法
    def bark(self):
        print('汪汪汪叫.....')


# 定义 Dog类的对象,查看是否可以调用 eat 方法
dog = Dog()
dog.eat()  # 子类对象调用父类中的方法

重写

重写:在子类中定义了和父类中名字相同的方法,就是重写
重写的原因:父类中的方法,不能满足子类对象的需求,所以重写
重写之后的特点:调用子类字节的方法,不再调用父类中的方法
重写的方式:
1.覆盖(父类中功能完全抛弃,不要,重写书写)
2.扩展(父类中功能还调用,只是添加一些新的功能)(使用较多)
覆盖:
1.直接在子类中定义和父类中名字相同的方法
2.直接在方法中书写新的代码
扩展:
1.直接在子类中定义和父类中名字相同的方法
2.在合适的地方调用父类中方法super().方法()
class Dog:
    def bark(self):
        print('汪汪汪叫.....')
​
​
class Tom(Dog):
    # Tom 类bark 方法不再是汪汪汪叫, 改为 嗷嗷嗷叫
    def bark(self):
        print('嗷嗷嗷叫...')


# 扩展
# class Tom(Dog):
#     def bark(self):
#         # 调用父类中的功能
#         super().bark()
#         super().eat()
#         # 书写扩展的新功能
#         print('摇尾巴...')

对象的划分

  • 实例对象

1.通过类名()创建的对象,我们称为实例对象,简称实例
2.创建对象的过程称为是类的实例化
3.我们平时所说的对象就是指实例对象(实例)
4.每个实例对象,都有自己的内存空间,在自己的内存空间中保存自己的属性(实例属性)
  • 类对象

1.类对象就是类,或者可以认为是类名
2.类对象是Python解释器在执行代码的过程中创建的
3.类对象的作用:
使用类对象创建实例类名()
类对象也有自己的内存空间,可以保存一些属性值信息(类属性)
4.在一个代码中,一个类只有一份内存空间

属性的划分

  • 实例属性

在init方法中,使用self.属性名=属性值定义
在方法中是使用self.属性名来获取(调用)
  • 类属性

在类内部,方法外部,直接定义的变量,就是类属性
使用: 类对象.属性名=属性值 or 类名.属性名=属性值
类对象.属性名 or 类名.属性名

方法的划分

  • 实例方法

# 在类中直接定义的方法 就是 实例方法
class Demo:
    def func(self):   # 参数一般写作 self,表示的是实例对象
        pass

# 对象.方法名()   不需要给 self 传参
  • 类方法

# 在方法名字的上方书写 @classmethod 装饰器(使用 @classmethod 装饰的方法)
class Demo:
    @classmethod
    def func(cls):  # 参数一般写作 cls, 表示的是类对象(即类名) class
        pass 

# 1. 通过类对象调用
# 类名.方法名()  也不需要给 cls 传参, python 解释器自动传递
# 2. 通过实例对象调用
# 实例.方法名()  也不需要给 cls 传参, python 解释器自动传递
  • 静态方法

# 在方法名字的上方书写 @staticmethod 装饰器(使用 @staticmethod 装饰的方法)
class Demo:
    @staticmethod
    def func():   # 一般没有参数
        pass 

# 1. 通过类对象调用
# 类名.方法名() 
# 2. 通过实例对象调用
# 实例.方法名()  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值