栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python基础(7)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python基础(7)

Python基础(7)

嵌套函数

函数定义与使用nonlocal关键词 LEGB规则面向对象类

类的定义类和对象的关系构造函数实例属性实例方法

实例方法的使用其他操作 类对象类属性类方法静态方法__del__方法(析构函数)和垃圾回收机制__call__方法和可调用对象

嵌套函数 函数定义与使用

def printname(isChnese,name,familyname):
    def inner_print(a,b):
        print('name:{}{}'.format(a,b))

    if isChnese:
        inner_print(familyname,name)
    else:
        inner_print(name,familyname)

printname(True,'三','张')
printname(False,'li','si')

#结果为:
name:张三
name:lisi
nonlocal关键词

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

global:用来声明全局变量

def outer():
    b = 2
    def inner():
        print('打印b:',b)
    inner()

outer()

#结果为:
打印b: 2

但如果要在嵌套函数中修改外层变量b则报错:

修改一:

def outer():
    b = 2
    def inner():
        b = 20
        print(b)
    inner()

outer()

#结果为
20

此时外层变量b与嵌套函数内部的b变量名一样,嵌套函数会以局部变量为准,即内层嵌套的b,下例同理,将嵌套函数的b在使用后修改报错,因为变量相同时,嵌套函数内只认内部变量,因此print打印b时,b还未被定义(b的定义在打印语句下面):

def outer():
    b = 2
    def inner():
        print('打印b:', b)
        b = 20
    inner()

outer()

#结果为(报错):
UnboundLocalError: local variable 'b' referenced before assignment

但在声明了b为nonlocal时:

def outer():
    b = 2
    def inner():
        nonlocal b
        print('打印b:', b)
        b = 20
        print('打印b:', b)
    inner()
	print('打印b:', b)
outer()

#结果为:
打印b: 2
打印b: 20
打印b: 20
LEGB规则

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

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

#结果为:
inner

将局部变量str注释后:

str = 'global str'
def outer():
    str = 'outer'
    def inner():
        # str = 'inner'
        print(str)
    inner()
outer()

#结果为:
outer

在注释“outer”后:

str = 'global str'
def outer():
    # str = 'outer'
    def inner():
        # str = 'inner'
        print(str)
    inner()
outer()

#结果为:
global str
面向对象




总结:

注:区分类与实例的属性和方法,二者不同!!!

类的定义

类定义了数据类型的属性(数据)和方法(行为),也就是说,类将行为和状态打包在一起。

类名一般首字母大写。

类和对象的关系

如果把对象比作一个饼干,则类就是制造饼干的模具。
对象也可以包含方法,对象是类的实例。
在Python中一切皆对象,类也称为类对象,类的实例也称为实例对象。

我们可以进一步说,一个Python对象包含如下部分:
1、id
2、type
3、value
(1)属性
(2)方法


样例(很重要!理解!):

class Student:
    def __init__(self,name,score):
        self.name_1 = name
        self.score_1 = score

    def print_information(self):
        print('{}的分数为:{}'.format(self.name_1,self.score_1))

print(Student)
print(type(Student))
S = Student('zzz',96)
print(S)
print(type(S))
S.print_information()

#结果为:


<__main__.Student object at 0x0000022B28AD9710>

zzz的分数为:96

解析:

Student为一个类,它的type是‘type’型,等同于一个模具,但模具内没有实例属性 (没有创建实例时实例属性并不存在,创建了实例后实例属性也是在实例对象中,而非模具中,所以下面提到的类方法和静态方法均不能访问实例属性, 看下图);S是创建的一个实例对象,它的type是一个类。

S = Student(‘zzz’,96)是将创建的实例对象的id赋值给了S。

在实例对象中,实则通过Student模具创建了实例对象,有id、type、和value,其中value又包含有属性和方法,所以创建的实例对象中有两个属性:name_1和score_1,而S = Student(‘zzz’,96)就是将对象‘zzz’和96的id赋值给了name_1和score_1,其实跟函数的赋值差不多。

方法的调用实际上是每个实例内共享了模具里方法的代码,但每个实例对象的方法id都是不一样的。

再来一个示例:

图解:

构造函数

init()方法

其本质有点像函数的赋值,将参数赋给了构造函数的形参,然后再赋给实例对象的参数属性。

实例属性

实例方法 实例方法的使用

注:图片中的say_score()等同于样例中的print_information()





直接使用类Student.say_score(a)时,解释器不会自动将self参数传入,所以需要在括号内加a,其作用就是将self地址传入,由下例可知,二者作用一样:

class Student:
    def __init__(self,name,score):
        self.name_1 = name
        self.score_1 = score

    def print_information(self):
        print('{}的分数为:{}'.format(self.name_1,self.score_1))

S = Student('zzz',97)
S.print_information()
Student.print_information(S)

#结果为:
zzz的分数为:97
zzz的分数为:97
其他操作

class Student:
    def __init__(self):
        self.name_1 = 'zzz'
        self.score_1 = 97

    def print_information(self):
        print('{}的分数为:{}'.format(self.name_1,self.score_1))

class Test:
    pass

S = Student()
print(isinstance(S,Student))
print(isinstance(S,Test))

#结果为:
True
False
类对象
class Student:
    pass

print(id(Student))
s = Student()
k = Student
z = k()
print(id(s))
print(id(k))
print(id(z))

#结果为:
2372211609384
2372218500880
2372211609384
2372220195840

print(id(Student))和print(id(k))的结果一样,他们都是类对象,而s和z则是根据类模板创造出的两个实例对象,因此id不一样

以下案例可以验证,Student的type是‘模具类’,即‘type’,而Student()是一个根据Student模具创建的实例对象

class Student:
    pass

print(type(Student))
S = Student()
print(S)

#结果为:

<__main__.Student object at 0x000001BB0CCEB128>
类属性



图解:

类方法

class Test:
    age = 18

    @classmethod
    def inner(cls):
        print('打印:',cls.age)

Test.inner()

#结果为:
打印:18
静态方法


但静态方法可以访问类属性。

class Test:
    age = 18

    @classmethod
    def inner(cls):
        print('打印:',cls.age)

    @staticmethod
    def add(a,b):
        print(a+b)

Test.add(1,6)

#结果为:
7
__del__方法(析构函数)和垃圾回收机制


下面重写了析构方法:

class Preson:
    def __del__(self):
        print('销毁:{}'.format(self))

s1 = Preson()
s2 = Preson()
print('over')

#结果为:
over
销毁:<__main__.Preson object at 0x0000021B4E1FB198>
销毁:<__main__.Preson object at 0x0000021B4E3993C8>

即创建两个实例对象后打印over,然后对象不使用则回收,调用析构方法来销毁。

下面用了del函数:

class Preson:
    def __del__(self):
        print('销毁:{}'.format(self))

s1 = Preson()
s2 = Preson()
del s2
print('over')

#结果为:
销毁:<__main__.Preson object at 0x00000130565993C8>
over
销毁:<__main__.Preson object at 0x00000130563FB198>

即创建了两个实例后调用del函数,销毁了s2,因此结果的第一行为s2的销毁结果,然后打印over,接着s1没有调用自动销毁。

__call__方法和可调用对象

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

其实就是()的用法!看下例:

class Test:
    def __call__(self, a):
        print(a)
        return a*2

s = Test()
j = s.__call__(5)
k = s(5)
print(j,k)

#结果为:
5
5
10 10

s()中的()就是调用了__call__方法。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/753258.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号