Day7_Python基础

1、nonlocal关键字

nonlocal 用来声明外层的局部变量
global 用来声明全局变量

# 测试 nonlocal、global 关键字的用法
a = 400

def outer():
    b = 100

    def inner():
        nonlocal b  # 声明外部函数的局部变量
        print("inner b:", b)
        b = 20
        global a    # 声明全局变量
        a = 1000
    inner()
    print("outer b:", b)

outer()
print("a:", a)

测试结果:
在这里插入图片描述

2、LEGB规则

Python 在查找“名称”时,是按照 LEGB 规则查找的:
Local–>Enclosed–>Global–>Built in

Local 指的就是函数或者类的方法内部
Enclosed 指的是嵌套函数(一个函数包裹另一个函数,闭包)
Global 指的是模块中的全局变量
Built in 指的是 Python 为自己保留的特殊名称。
如果某个 name 映射在局部(local)命名空间中没有找到,接下来就会在闭包作用域(enclosed)进行搜索,如果闭包作用域也没有找到,Python 就会到全局(global)命名空间中进行查找,最后会在内建(built-in)命名空间搜索 (如果一个名称在所有命名空间中都没有找到,就会产生一个 NameError)。

#测试 LEGB

str = "global"
def outer():
    str = "outer"
    def inner():
        str = "inner"
        print(str)

    inner()

outer()

以此将代码中的str注释掉,观察控制台打印的内容,便可理解LEBG的搜索顺序。

3、类的定义

**类将行为和状态打包在一起。**如图所示:在这里插入图片描述
对象是类的具体实体,一般称为“类的实例”。
类可看做饼干模具,对象就是根据这个“模具”制造出的“饼干”

从一个类创建对象时,每个对象会共享这个类的行为(类中定义的方法),但是会有自己的的属性值(不共享状态)。总的来说就是“方法代码是共享的,属性数据不共享”如图所示:

在这里插入图片描述

定义类的语法格式如下:
class 类名:
类体
注意:
(1)类名必须符合“标识符”的规则;一般规定,首字母大写,多个单词使用“驼峰原则”。
(2)类体中我们可以定义属性和方法。
(3)属性用来描述数据,方法(函数)用来描述这些数据的相关操作。

举例:

class Student:
    def __init__(self, name, score):   # 构造函数第一个参数必须是self
        self.name = name     # 属性实例
        self.score = score

    def say_score(self):
        print("{0}的分数是:{1}".format(self.name, self.score))


s1 = Student('kdx', 99)   # s1是实例对象,自动调用__init__()方法
s1.say_score()

测试结果:
在这里插入图片描述

4、__init__构造方法和__new__方法

一个Python对象包含如下部分:
(1)id (identity识别码)
(2)type(对象类型)
(3)value(对象的值)

<1> 属性(attribute)
<2> 方法(method)

创建对象,我们需要定义构造函数__init__()方法。

init()的要点如下:
1、名称固定,必须为:init()
2、第一个参数固定,必须是:self self指的是刚创建好的实例对象
3、构造函数通常用来初始化实例对象的实例属性

    def __init__(self, name, score):   # 构造函数第一个参数必须是self
        self.name = name     # 属性实例
        self.score = score

4、通过“类名(参数列表)”来调用构造函数,调用后将创建好的对象返回给相应的变量。
举例:s1 = Student('kdx', 99) # s1是实例对象,自动调用__init__()方法
5、init()方法:初始化创建好的对象,初始化指的是给实例属性赋值
6、new()方法:用于创建对象,但是一般无需定义该方法
7、如果我们不定义__init__方法,系统会提供一个默认的__init__方法。

注意:Python中的self相当于C++中的self指针,JAVA和C#中的this关键字。Python中,self必须为构造函数的第一个函数,名字可以任意修改。但一般遵守惯例,都叫做self。

5、实例属性和实例方法

实例属性
(1)实例属性一般在__init__()方法中通过代码定义:
self.实例属性名 = 初始值
(2)在本类的其他实例方法中,也是通过self进行访问:
self.实例属性名
(3)创建实例对象后,通过实例对象访问:
obj01 = 类名() # 创建对象,调用__init__()初始化属性
obj01.实例属性名 = 值 # 可以给已有属性赋值,也可以新加属性

实例方法
定义格式:在这里插入图片描述
注意:
(1)定义实例方法时,第一个参数必须为self。self指当前的实例对象。
(2)调用实例方法时,不需要也不能给self传参,self由解释器自动传参(传地址)。

实例对象的方法调用本质:在这里插入图片描述
其他操作:
(1)dir(obj)可以获得对象的所有属性、方法
(2)obj.dict 对象的属性字典
(3)pass 空语句
(4)isinstance(对象,类型) 判断“对象”是不是“指定类型”

6、类对象

当解释器执行class语句时,就会创建一个类对象。

# 测试类对象

class student:
    pass

print(type(student))
print(id(student))

s2 = student
s1 = s2()
print(s1)

测试结果:在这里插入图片描述
注意:pass语句为空语句,只是作为一个占位符存在。写代码时可以暂时用pass代替后期再补上。

7、类属性

类属性从属于类对象,可以被所有实例对象共享

定义方式:
class 类名:
类变量名 = 初始值

# 测试类属性

class Student:

    sch = "HeFei"  # 类属性
    count = 0   # 类属性


    def __init__(self, name, score):
        self.name = name       # 实例属性
        self.score = score
        Student.count += 1

    def say_score(self):      # 实例方法
        print("我的学校是:{0}".format(Student.sch))
        print("{0}的分数是{1}".format(self.name, self.score))

s1 = Student("kdx", 89)   # s1是实例对象,自动调用__init__()方法
s1.say_score()
print("一共创建了{0}个Student对象".format(Student.count))

测试结果:在这里插入图片描述

8、类方法

类方法是从属于“类对象”的方法。**类方法通过装饰器@classmethod 来定义,**格式如
@classmethod
def 类方法名(cls [ , 形参列表]):
函数体
要点如下:

  1. @classmethod 必须位于方法上面一行
    2. 第一个 cls 必须有;cls 指的就是“类对象”本身;
  2. 调用类方法格式:“类名.类方法名(参数列表)”。 参数列表中,不需要也不能给 cls 传值。
  3. 类方法中访问实例属性和实例方法会导致错误
    5. 子类继承父类方法时,传入 cls 是子类对象,而非父类对象
# 测试类方法

class Student:

    comp = "SSS"  #类属性

    @classmethod
    def printComp(cls):
        print(cls.comp)

Student.printComp()

测试结果:在这里插入图片描述

9、静态方法

(1)Python 中允许定义与“类对象”无关的方法,称为“静态方法”。
(2)“静态方法”和在模块中定义普通函数没有区别,只不过“静态方法”放到了“类的名字空间里面”,需要通过“类调用”。
(3)静态方法通过装饰器@staticmethod 来定义,格式如下:
@staticmethod
def 静态方法名([形参列表]) :
函数体
要点如下:

  1. @staticmethod 必须位于方法上面一行
  2. 调用静态方法格式:“类名.静态方法名(参数列表)”。
  3. 静态方法中访问实例属性和实例方法会导致错误

测试:

# 测试静态方法

class Student:
    comp = "SSS"  # 类属性

    @staticmethod
    def add(a, b):  # 静态方法
        print("{0}+{1}={2}".format(a, b, a+b))
        return a+b

Student.add(23, 45)

测试如图:在这里插入图片描述

10、内存分析实例对象和类对象创建过程(重要)

在这里插入图片描述
在这里插入图片描述

11、__del__方法(析构函数)和垃圾回收机制

__del__方法被称为“析构函数”,用于实现对象被销毁时的所需的操作。比如:释放对象占用的资源,例如:打开的文件资源、网络连接等。

Python实现自动的垃圾回收,当对象没有被引用(引用计数为0),由垃圾回收器调用__del__方法。也可以使用del语句删除对象。
测试:

# 测试析构函数

class Person:
    def __del__(self):
        print("销毁对象:{0}".format(self))
        
p1 = Person()
p2 = Person()
del p2
print("程序结束")

测试结果如图:
在这里插入图片描述

12、__call__方法和可调用对象

定义了__call__方法的对象,称为“可调用对象”,即该对象可以像函数一样被调用。

# 测试__call__可调用对象

class SalaryAccount:
    '''工资计算类'''
    def __call__(self, salary):
        yearSalary = salary*12
        daySalary = salary//30
        hourSalary = daySalary//8

        return dict(monthSalary=salary, yearSalary=yearSalary, daySalary=daySalary, hourSalary=hourSalary)

s = SalaryAccount()

print(s(13000)) # 可以像调用函数一样调用对象的__call__方法

测试如图
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LeetCode_C++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值