python学习笔记 函数作用域.装饰器.文件

四,函数作用域和匿名函数

匿名函数

lambda:

  • 方法:lambda 参数:表达式 (可以带或不带参数)

    ​ 注意:复杂逻辑不用

匿名函数应用场景:

​ 简单函数: 简单的函数,可以不用使用def定义一个函数,使用匿名函数即可

​ 函数调用:类似于filter、map等函数里面,可以使用匿名函数来处理

​ 提高开发效率:匿名函数的合理利用能够让那个代码更加简洁


1.全局变量,局部变量

num = 100          全局变量;函数外定义的变量
def f():
    num = 200      局部变量;函数内部定义的变量,函数外无法调用
    print("2",num)
print("1",num)
f()
#1 100
#2 200


2.局部变量改变全局变量:

global:

def f():
    global num     此处改变了全局变量
    num = 200      此处改变了全局变量
    print("2",num)

nonlocal

函数内部:函数内部的变量,作用域只在函数内部,函数内部不可以直接更改函数外部的变量

global: 函数内部如果需要改变全局变量,就需要使用global修饰变量

nonlocal:在函数嵌套函数的情况下,同样也有函数作用域的问题,但是python3中提供了方便,只需要使用nonlocal就可以在里层函数内部修改外部函数变量(下面有详细)

闭包

闭包是函数里面嵌套函数,外层函数返回里层函数,这种情况称之为闭包

闭包是概念,不是某种函数类型,和递归的概念类似,就是种特殊的函数调用

闭包可以得到外层函数的局部变量,是函数内部和函数外部沟通的桥梁

嵌套:

def f1():
     print("sss")
     def f2()
        print("dddd")
     return f2
y=f1()
y()
1,直接调用f1函数,此时,执行了print ,定义了一个f2函数同时反回了f2的函数名
2,用变量y接收f2函数名
3,变量名+(),实现了函数的调用

函数名即变量


函数嵌套

函数嵌套时,内层函数想要使用外部函数变量,nonlocal

def f1():
     num = 88
     def f2():
         nonlocal num
         num += 1
         return num
     return f2()      此处表示调用f2()函数
 y=f1()
 print(y)


递归函数

函数里调用自身

求阶乘:
def f(n):
    if n==1:
       return 1       此为终止条件
    return n*f(n-) 

慎用递归这不利于电脑的运行


五,类定义、属性、初始化

类,实例(面向对象编程)


类 抽象的模版 是一个独立存放变量(属性/方法)的空间

实例:根据类创建出来的一个个具体的对象,拥有相同的标志但是各自的数据不同

定义:类的定义使用关键字 class 大驼峰命名法:每个单词的首字母大写

class Cat:
     pass


实例化对象:

​ kitty = Cat( )

属性:(句点法给实例赋值)

kitty.color = 'white'
kitty.eat = 'milk'

color eat就是我们kitty对象的实例属性


属性

class Cat:
    count = 0       #类属性,记录你实例化对象的次数
    def_init_(self,color,eat):
         self.color = color      #实例属性
         self.eat = eat
         Cat.count +=1      #类名,类属性名,内部调用

kitty = Cat("white","milk")
print(kitty.color)
print("创建了".format(Cat.count))   #外部调用1 类名.类属性名
print(kitty.count)                 #外部调用2 实例名.类属性名
print(kitty.color)                 #实例调用实例属性
                   注意:类是不能调用实例属性

实例可以访问实例属性,实例可以访问类属性

类只能访问类属性


私有属性:

在python中有两私有属性,分别是在属性前加 一个下换线(_) 和 两个下划线(__)

单下划线开头:告诉别人这是私有属性,依然可以使用

双下划线开头:外部不能使用

class Cat:
     def__init__(self,color,eat,age):
         self.color = color
         self._eat = eat      #外部可以访问
         self.__age = age     #外部不可访问

kitty = Cat("whlit","mlik",5)
print(kitty.coclor)
print(kitty._eat)
#print(kitty.__age) 此会报错


方法

方法----和某个特定的类相关联的函数

类方法:类中的方法,就是函数

self:Self 代表的是实例本身

调用:方法的调用和属性调用一样,通过点操作符调用,传参和函数传参一样

class Cat:
    def add_cat(cat):
    print("{} {}".format(cat.color, cat.age))   注意也可在此调用私有方法

kitty = Cat()
kitty.color = "white"
kitty.age = 3

Cat.add_cat(kitty)  #类名.方法名()   函数调用1
  结果 :white-3
kitty.add_cat()     #结果一样          函数调用2


六,继承,多继承,魔术方法


继承

子类(派生类)只继承了一个父类(基类)

class A:
     def f(self):
        print("A")
class B:
     def f(self):                    E分别继承C,D。C继承A  D继承B
        print("B")
class C(A):
     def f(self):
        print("C")
class D(B):
     def f(self):
        print("D")
class E(C,D):
     def f(self):
        print("E") 

e = E()   #实例化对象
e.f()     # 得到E  调用方法,self始终指向的是实例对象e,所以方法选择的优先级始终从E类开始
            E--->C--->A--->D--->B 方法选择优先级


多继承

子类继承了多个父类

class F:
     def f(self):
        print("F")
class A(F):
     def f(self):
        print("A")
class B(F):
     def f(self):       #E分别继承C,D。C继承A,D继承B  A,B继承了F
        print("B")              #E--->C--->A---D--->B-->F
class C(A):
     def f(self):
        print("C")
class D(B):
     def f(self):
        print("D")
class E(C,D):
     def f(self):
        print("E") 

类名.mor() 查看所有继承关系的方法

类名.__ bases__ 查看继承所有父类


魔术方法

__str__     把一个类的实例变成字符串
__repr__    __str__的备胎,如果有__str__,print会先执行__str__
 
class A:
    pass
a=A()
print(a) #对象地址

class A:
    def __str__(self)    #返回必须是字符串
        return "str"
a=A()
print(a)  

__call__    正常情况下,实例是不能像函数一样被调用,要想能调用使用这个
class A:
    def __init__(self, num):
        self.num =num
    def __add__(self, other):     #魔术方法 +
        res = self.num + other.num
        return res
    def __call__(self):
        prnit("成功")
one = A(55)
two = A(66)
print(one + two)   #121
one()    #调用成功


七,描述器和装饰器

__new__方法

相同的东西 不必在重新创建

 __new__:单例模式
class A(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, 'instance'):    # 判断是不是已经有实例存在了
            cls.instance = super().__new__(cls)     # 新建一个实例
        return cls.instance

    def __init__(self):
        self.name = "DMC"
        
one = A()
print(one, id(one))
two = A()
print(two, id(two))

# 数据库连接池


定制属性访问

class Rectangle(object):
    def __init__(self, length, width):
        self.length = length
        self.width = width

    def __getattr__(self, item):    # 当属性不存在时,调用此魔术方法,实现不报错
        print("没有这种方法")

    def area(self):
        areas = self.length * self.width
        # print(areas)
        return "面积是:{}".format(areas)
        
a = Rectangle(66, 88)


对象属性的增删改查

增,无则增,有则改
a.num = 6               #第一种改方法
setattr(a, "num", 6)    #第二种改方法
a.__setattr__("num", 6) #此为第二种的对应的魔术方法
print(a.num)
a.num = 8
setattr(a, "num", 10)
a.__setattr__("num", 12)
print(a.num)

# 查
print(hasattr(a, "num"))    # bool值
print(getattr(a, "num"))    # 获取属性值
print(a.__getattribute__("num"))    # 获取属性值

# 删
# del a.num          #直接删除这种属性
# delattr(a, "num")  #与上同理
a.__delattr__("num") 
a.num                #没有这种方法  调用实现不报错

# 魔术方法,给了我们一个自定义的接口,函数执行的底层其实就是去调用了魔术方法,我们只需要修改一下对应的魔术方法,实现自定义


描述符

class A:
    def __get__(self, instance, owner):
        print("__get__")

    def __set__(self, instance, value):
        print("__set__")

    def __delete__(self, instance):
        print("__delete__")


class B:
    a = A()  # 把A的实例对象拿来做了B的类属性,描述符

    def __init__(self):
        self.name = "句号"


b = B()  # 类的实例化
print(b.name)   # 输出对象内容
b.a  # 获取B的类属性(A的实例),会去执行__get__
b.a = 88  # 重新赋值, 会去执行__set__
del b.a     # 删除,会去执行__delete__


装饰器

装饰器的本质还是一个闭包

def outer(func):
    def inner():
        print("前增功能")
        func()
        print("后增功能")
    return inner

@outer  # 1.执行outer函数,并将下方的函数名作为参数赋值给了outer函数2.将outer函数的返回值重新赋值给了下方的函数
def f1():
    print("原功能")

f1()
# f1 = outer(f1)
# f1()

@outer
def f2():
    print("原功能f2")

@outer
def f3():
    print("原功能f3")

# .......
@outer
def f100():
    print("原功能f100")


一个装饰器去装饰不同参数个数的不同函数

# 为了方便接收不同参数个数的每个函数,*args, **kwargs
def outer(func):
    def inner(*args, **kwargs):
        print("前增")
        func(*args, **kwargs)
        print("后增")
    return inner

@outer
def f1():
    print("没有参数")

f1()

@outer
def f2(a):
    print(a)

f2(6)

@outer
def f3(a, b):
    print(a + b)

f3(4, 6)

@outer
def f4(a, b, c):
    print(a + b + c)

f4(4, 5, c=6)


多个装饰器

def outer_0(func):
    def inner(*args, **kwargs):      # 为了方便接收不同参数个数的每个函数,*args, **kwargs
        print("start")
        func(*args, **kwargs)
        print("end")
    return inner

# 多个装饰器装饰同一个函数
def outer(func):
    def inner(*args, **kwargs):
        print("前增")
        func(*args, **kwargs)
        print("后增")
    return inner

@outer_0
@outer
def f1():
    print("原功能")

f1()


类做装饰器

class TestClass:
    """这是一个用来做装饰器的类"""
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print('__call__')
        print("前增")
        self.func()
        print("后增")

@TestClass
def f():
    print("原功能")

f()


内置装饰器

class Cat:
    name = "猫"

    def __init__(self, color, eat):
        self.color = color
        self.eat = eat

    @property   # (方法变属性)
    def print_cat(self):
        print("{},{}".format(self.color, self.eat))

    @classmethod
    def func1(self, cls):
        print("ok")
        print(cls.name)

    @staticmethod   # 静态方法(解绑)
    def func():
        print("不需要self参数也能运行")
        print("不需要实例化也能运行")

kitty = Cat('white', "food")
# kitty.print_cat()
# kitty.color
kitty.print_cat    #white,food
kitty.func()     #不需要self参数也能运行 不需要实例化也能运行
Cat.func()       #不需要self参数也能运行 不需要实例化也能运行


八,文件

文件基本操作


打开 读取 关闭 和 with

#打开  r
f = open(r"C:\Users\JiaNeng\Desktop\test.txt", "r", encoding="utf-8")
print(f.read())
f.close() #关闭

f = open("test.txt", "r", encoding="utf-8")
print(f.read())
f.close()
#读取  w
f = open("test1.txt", "w", encoding="utf-8")    # 无,新建
f.write("dante\n")
f.close()

f = open("test.txt", "w", encoding="utf-8")    # 有,覆盖
f.write("dante\n")
f.writelines("nero\n")
f.writelines(["viger\n", "2", "5"])   # 写入字符串或者字符串序列
# f.flush()
f.close()

f = open("test.txt", "r", encoding="utf-8")
print(f.read())   #读写入的内容
f.close()
 
with 可以自动关闭 比较保险 下面有用法实例

tell():以bytes为单位,从文件头到当前指针的位置

seek():以bytes为单位,指针的偏移量

print("源氏\n".encode("utf-8"))   # b'\xe5\x8f\xb6\xe8\x90\xbd\n'

with open("test.txt", "r", encoding="utf-8") as f:
    print("1:", f.tell())
    print(f.read())
    print("2:", f.tell())
    f.seek(0)
    print("3:", f.tell())
    f.seek(2)
    print("4:", f.tell())
    #print(f.read())  这个报错 一个中文utf-8是三个字节,移动两个字节,字被拆开了


总结

#r和w
#r只读
with open("test.txt", "r", encoding="utf-8") as f:
    print(f.tell())
    print(f.read())

#w只写,文件不存在新建并写入,文件存在就直接重写
#不存在新建
with open("test1.txt", "w", encoding="utf-8") as f:
    f.write("新建并写入")

#存在覆盖
with open("test.txt", "w", encoding="utf-8") as f:
    f.write("覆盖")


非文本的读取和写入

# rb和wb,只读和只写,非文本的读取和写入
img = ""
with open("任意的图片.png", "rb")as f:
    img = f.read()
with open(" .png", "wb")as f:
    f.write(img)


a追加

# a追加:在文件末尾增加
文件不存在,新建,再写入
with open("test2.txt", "a", encoding="utf-8")as f:
    f.write("haha")
# 文件存在,在文件末尾增加
with open("test.txt", "a", encoding="utf-8")as f:
    print(f.tell())
    f.write("追加")


r+ w+ a+

r+:读写,指针在文件开头
w+:读写,不存在新建,存在覆盖
a+:读写,不存在新建,存在文件末尾追加

用法实例:

with open("test.txt", "r+", encoding="utf-8") as f:
    print("1:", f.tell())
    print(f.read())
    print("2:", f.tell())
    f.write("1")
    print("3:", f.tell())
    print(f.read())

with open("test.txt", "w+", encoding="utf-8") as f:
    print("*"*50)
    print("1:", f.tell())
    print(f.read())
    print("2:", f.tell())
    f.write("新建并写入")
    print("2:", f.tell())
    f.seek(0)
    print(f.read())

print("*"*50)
with open("test.txt", "a+", encoding="utf-8")as f:
    print(f.tell())
    f.write("追加")
    f.seek(0)
    print(f.read())


read() readline() readlines()

read():光标到文件末尾,字符串
readline():读一行,字符串
readlines():列表。[“第一行”, “第二行”。。。。]

用法实例:

with open("test.txt", "r", encoding="utf-8") as f:
    file = f.read()
    print(file.strip())  # 新建并写入追加
    print(type(file))   # <class 'str'>

with open("test.txt", "r", encoding="utf-8") as f:
    line = f.readline()
    # print(line)
    print(type(line))   # <class 'str'>
    while line:
        print(line.strip())
        line = f.readline()

with open("test.txt", "r", encoding="utf-8") as f:
    lines = f.readlines()
    print(lines)    # ['新建\n', '并\n', '写入\n', '追加']
    print(type(lines))  # <class 'list'>


上下文管理工具

# __enter__/__exit__
from datetime import datetime

class Runtime:
    def __enter__(self):
        self.start_time = datetime.now()
        print("程序开始运行的时间:{}".format(self.start_time))
        return self.start_time

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.end_time = datetime.now()
        print("程序结束运行的时间:{}".format(self.end_time))
        print("程序运行的时间:{}".format(self.end_time - self.start_time))

run = Runtime()
with run as a:  # 上下文管理器
    print("a:", a)
    for i in range(10000000):
        type("helloTZ")
        # isinstance("helloTZ", str)

# a 是__enter__的返回值,with会把这个返回值通过as赋值给a


IO流

使用时先导入模块

###StringIO(字符流):

import io
sio  = io.stringIO()  #实例化,创建了一个对象,进行保存读取的
sio .write("hello")  #写
print(sio.getvalue()) #读
sio.close()

###BytesIO(字节流):

bio = io.BytesIO() #同上
bio.write(b'abcd') #转义
print(type(b'abcd'))  #<class 'bytes'>
print(bio.grtvalue())
bio.close()


使用工具

os模块仅作了解

import os

os.system("pwd")  # 需连虚拟机
路径拼接
url1 = os.path.join('home', 'pyvip', 'project')
print(url1)

os.mkdir('test')    # 创建文件夹,如果已经存在,报错
os.rename('test', 'test1')  # 修改文件夹名

​ 模块 shutil

import shutil

将文件移动到目标文件夹
shutil.move('homework.py', 'test1')  # 相对路径
shutil.move(r'C:\Users\JiaNeng\Desktop\test.txt', r'E:\fei\讲义\1-基础班') # 绝对路径

复制,将前一个复制到后一个
shutil.copytree(r"test1", r"..\lesson16\test1")

删除
shutil.rmtree(r"E:\fei\basic45\lesson16\test")
shutil.rmtree(r"E:\fei\basic45\lesson16\test1")


九,异常

异常的种类

NameError SyntaxError TypeError

异常本身就是异常类的实例


异常处理

try:
    先执行,异常,捕获异常,执行except里面的代码
    先执行,无异常,不再执行except里面的代码
except:
    捕获异常时,执行的功能块
扩展:捕获具体的异常:让你捕获你想要捕获的异常,不想捕获的正常抛出异常
try:
    1/0
    # 5 - "a"
except TypeError:
    print("类型错误")
except FileNotFoundError:
    print("文件错误")
except Exception as e:  #e输出了Exception 里的错误描述
    print("其他的普通异常")
    print(e)
1/0  # ZeroDivisionError: division by zero
 自动抛出异常
 raise
 try:
     raise TypeError("主动抛出的类型错误")    # 自制异常
 except TypeError:
     print("类型错误")
 except FileNotFoundError:
     print("文件错误")
 except Exception as e:
     print("其他的普通异常")
     print(e)
# 自定义异常类型
class ZiDingYiError(Exception):
    pass


def func(name):
    if name == 'Dante':
        print("允许登录")
    else:
        raise ZiDingYiError("你不是Dante,不许登录!!!!")


try:
    func("Dante")
except Exception as e:
    print(e)


断言 assert

a = 1
b = 2
print(a > b)    # False
print(a < b)    # True

assert a < b
 assert a > b    # 条件不满足时,抛出AssertionError异常,后续程序终止
print("ok")  # 条件满足,正常执行

 比较
 def func(name):
     if name == "viger":
         raise TypeError("黑名单用户,拒绝访问")


# func("viger")

def func(name):
    assert name != "Nero"    # ====>"Nero" != "Nero"

func("Nero")  # AssertionError
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值