python函数和面向对象实例分析

python函数和面向对象实例分析

这篇文章主要介绍“python函数和面向对象实例分析”,在日常操作中,相信很多人在python函数和面向对象实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python函数和面向对象实例分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    函数

    python中『一切皆对象』, 函数也不例外.

    python函数和面向对象实例分析

    在之前所学的C++Java中, 可以发现函数的返回值要么为空, 要么是某种数据类型, 但是在python中, 返回值可以是任何对象, 包括函数.

    函数参数

    函数的参数种类比较多, 主要有:

    1.位置参数 (positional argument): 就是最常见的x, y等

    2默认参数 (default argument): 给定一个默认值, 用户也可以传入实参来调整.

    deffunc(x,y=3):print(x+y)func(1)#4func(1,666)#667

    3.可变参数 (variable argument): 不限制输入参数的个数, 传入后自动保存为元组类型.

    1.*args是可变参数,args接收的是一个tuple

    defprintinfo(arg1,*args):print(arg1)print(args,type(args))printinfo(10)#仅一个参数,没有属于args的.#10#()<class'tuple'>printinfo(70,60,50)#除arg1位置匹配的,其他都传入给可变参数#70#(60,50)<class'tuple'>

    4.关键字参数 (keyword argument): 不限制关键字的个数和命名, 传入后自动保存为字典的形式.

    1.**kw是关键字参数,kw接收的是一个dict

    defprintinfo(arg1,*args):print(arg1)print(args,type(args))printinfo(10)#仅一个参数,没有属于args的.#10#()<class'tuple'>printinfo(70,60,50)#除arg1位置匹配的,其他都传入给可变参数#70#(60,50)<class'tuple'>

    5.命名关键字参数 (name keyword argument)

    1.命名关键字参数是为了限制调用者可以传入的『参数名』,也可以提供默认值.

    2.与关键字参数不同的是, 关键字参数的名字和值都是任意的, 后续再进行匹配使用, 而命名关键字则只能接受给定的关键字作为参数.定义命名关键字参数

    3.不要忘了写分隔符*, 否则定义的是位置参数, 命名关键字参数调用函数时必须给定参数名.

    defperson(name,*,age,height=1.90):print(f'{name}今年{age}岁,身高{height:.2f}m')person('张三',age=18,height=1.80)#张三今年18岁,身高1.80mperson('李四',age=18)#李四今年18岁,身高1.90mperson('王五')#TypeError,需要传入给定关键字

    6.参数组合

    Python中定义函数时, 以上这5种参数都可以使用, d但最多可以使用4种, 并且要注意顺序:

    1.位置参数、默认参数、可变参数和关键字参数.

    2.位置参数、默认参数、命名关键字参数和关键字参数.

    变量作用域

    在python程序中, 处于不同位置的变量, 有不同的作用域.

    • 定义在函数内部的变量拥有局部作用域, 该变量称为局部变量.

    • 定义在函数外部的变量拥有全局作用域, 该变量称为全局变量.

    • 局部变量只能在其被声明的函数内部访问, 而全局变量可以在整个程序范围内访问.

    需要注意的是:

    • 当局部变量试图访问全局变量时, 一定要在函数内声明global.

    • 当局部变量与全局变量命名冲突时, 程序会优先选择局部变量.

    内嵌函数和闭包

    内嵌函数就是在外层函数内定义内层函数.

    defouter():print('outer函数在这被调用')definner():print('inner函数在这被调用')inner()#该函数只能在outer函数内部被调用outer()#outer函数在这被调用#inner函数在这被调用

    闭包是一个比较重要的语法结构, 结构上与内嵌函数类似, 区别在于返回值, 闭包的外层函数返回值是一个函数.

    如果在一个内部函数里对外层非全局作用域的变量进行引用, 那么内部函数就被认为是闭包.

    通过闭包可以访问外层非全局作用域的变量, 这个作用域称为闭包作用域.

    deffunX(x):deffunY(y):print('使用funY(y)')returnx*yreturnfunYi=funX(8)print(type(i))#<class'function'>print(i(5))#40

    注意到上述代码中, 内部函数FunY中使用了外部非全局作用域的变量x.

    同样是, 函数内嵌套的函数作用域也需要特别注意, 若我们需要修改闭包内的变量, 需要使用nonlocal关键字.

    num=999defouter():num=10definner():nonlocalnum#nonlocal关键字声明num=100print(f'inner中num={num}')inner()print(f'outer中num={num}')outer()#inner中num=100#outer中num=100print(f'全局中num={num}')#全局中num=999

    lambda 表达式

    lambda需要注意的是:

    • 匿名函数没有return, 表达式本身就是返回值.

    • 匿名函数拥有『自己的命名空间』, 不能访问参数列表之外或全局变量.

    匿名函数主要适用于函数式编程(函数不会影响函数之外的内容)的一些高阶函数中. 例如map映射和filter过滤, 当然也可以在自己自定义函数中使用.

    odd=lambdax:x%2==1templist=filter(odd,[1,2,3,4,5,6,7,8,9])print(list(templist))#[1,3,5,7,9]m1=map(lambdax:x**2,[1,2,3,4,5])print(list(m1))#[1,4,9,16,25]

    面向对象

    三大特性

    面向对象就必须了解三大特性:

    • 封装: 把客观事物封装成抽象的类, 让数据和方法给信任的类或对象操作, 而隐藏部分信息.

    • 继承: 子类自动共享父类的属性和方法.

      • 一般认为一个类是自身的子类;

      • 可以使用issubclass(B, A)查看B是否是A的子类.

      • python也支持多继承, 但会使得类的整体层次复杂, 所以并不建议使用.

    • 多态: 同一个方法的调用, 会由于不同对象而得到不同的结果.

      • 必要条件是继承方法的重写.

    类、类对象 和 实例对象

    • 类: 就是指对类的定义

    • 类对象: 是在创建类的时候, 在内存开辟的一个空间, 一个类只有一个类对象.

    • 实例对象: 通过实例化类创建的对象, 可以有多个.

    类属性 和 对象属性

    • 类属性: 类定义内, 类方法外定义的变量称为类属性, 类属性属于类对象, 可以被多个实例化对象所共享, 就像我们都有一个家, 名字叫中国一样.

    • 对象属性: 对象属性和具体创建的对象实例直接相关, 并且相互之间不共享属性, 就像我的老婆只是我的一样.

    classA():a=0#类属性def__init__(self,xx):A.a=xx#使用类属性可以通过(类名.类属性)调用。

    有一些操作属性的方法:

    • 使用hasattr(object, name)来判断对象是否包含对应的属性或方法.

    • 使用getattr(object, name)来获取属性或方法.

    • 使用setattr(object, name, value)来修改属性值, 或创建新的属性和值.

    • 使用delattr(object, name)来删除属性.

    classA(object):name='张三'defset(self,a,b):x=aa=bb=xprint(a,b)a=A()print(hasattr(a,'name'))#判断是否有name属性Trueprint(hasattr(a,'set'))#判断是否有set方法Truex=getattr(a,'name')#获取属性值print(x)#张三c=getattr(a,'set')#获取方法c(a='1',b='2')#21

    私有

    私有属性和方法仅需在定义命名的时候加上两个下划线"__"即可.

    相对于公有属性和公有方法来说, 私有属性和私有方法更加的安全. 从定义上来说, 将需要安全保护的属性和方法封装为私有, 可以阻止外部直接调用, 而必须使用实例化对象方法类方法进行调用, 从而提高安全性.

    但在python中的私有是『伪私有』, 即可以使用类名, 通过object._className__attrName访问私有属性,用object._className__func()访问私有方法.

    classJustCounter:__secretCount=0#私有变量publicCount=0#公开变量defcount(self):self.__secretCount+=1self.publicCount+=1print(self.__secretCount)counter=JustCounter()counter.count()#1print(counter.publicCount)#1#特殊方法依旧可以访问print(counter._JustCounter__secretCount)#1#直接访问则会报错.print(counter.__secretCount)

    实例直接使用就可以增加属性了, 这点需要注意一下.

    classB:deffunc(self):print('调用func方法')b=B()print(b.__dict__)#查看属性{}b.name='张三'b.age=18print(b.__dict__)#查看属性{'name':'张三','age':18}b1=B()print(b1.__dict__)#查看属性{}

    魔法方法

    基本的魔法方法

    魔法方法基本上是被下划线包围的一些特殊方法. 相比于普通的方法, 它能够在适当的时候自动调用. 第一个参数一般是cls『类方法』或者self『实例方法』.

    • __init__(self[, ...])构造器, 当一个实例被创建的时候调用的初始化方法.

    • __new__(cls[, ...])在一个对象实例化的时候所调用的第一个方法, 在调用__init__初始化前, 先调用__new__.

      • 需要注意的是,__new__的返回值必须为当前类的实例, 否则将不会调用__init__初始化.

      • 主要是在继承一些不可变的class(比如int, str, tuple)时, 提供一个自定义该类实例化过程的途径.

    • __del__(self)析构器, 当一个对象将要被系统回收之时调用的方法.

    • __str__(self): 当你打印一个对象、使用%s格式化或使用str强转数据类型的时候,触发__str__.

    • __repr__(self)__str__(self)的备胎, 情况类似, 不过自定义时往往更加准确, 主要用于调试.

    算术运算符

    普通的计算在对象中是无法进行的, 需要自定义计算方式.

    __add__(self, other)定义加法的行为:+

    __sub__(self, other)定义减法的行为:-

    __mul__(self, other)定义乘法的行为:*

    __truediv__(self, other)定义真除法的行为:/

    __floordiv__(self, other)定义整数除法的行为://

    __mod__(self, other)定义取模算法的行为:%

    __divmod__(self, other)定义当被divmod()调用时的行为

    divmod(a, b)把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)

    __pow__(self, other[, module])定义当被power()调用或**运算时的行为

    __lshift__(self, other)定义按位左移位的行为:<<

    __rshift__(self, other)定义按位右移位的行为:>>

    __and__(self, other)定义按位与操作的行为:&

    __xor__(self, other)定义按位异或操作的行为:^

    __or__(self, other)定义按位或操作的行为:|

    还有对应的反运算符, 在之前加上r即可, 例如__rsub__. 对应增量赋值运算符, 在之前加上i即可, 例如__isub__.

    属性访问

    __getattr__(self, name): 定义当用户试图获取一个不存在的属性时的行为.

    __getattribute__(self, name): 定义当该类的属性被访问时的行为(先调用该方法, 查看是否存在该属性, 若不存在, 接着去调用__getattr__).

    __setattr__(self, name, value): 定义当一个属性被设置时的行为.

    __delattr__(self, name): 定义当一个属性被删除时的行为.

    描述符

    描述符就是将某种特殊类型的类的实例指派给另一个类的属性.

    __get__(self, instance, owner): 用于访问属性, 它返回属性的值.

    __set__(self, instance, value): 将在属性分配操作中调用, 不返回任何内容.

    __del__(self, instance): 控制删除操作, 不返回任何内容.

    迭代器和生成器

    迭代器

    迭代是Python最强大的功能之一, 是访问集合元素的一种方式.

    • 迭代器是一个可以记住遍历的位置的对象.

    • 迭代器对象从集合的第一个元素开始访问, 直到所有的元素被访问完结束.

    • 迭代器只能往前不会后退.

    • 字符串, 列表或元组对象都可用于创建迭代器.

    迭代器有两个基本的方法:iter()next():

    • iter(object)函数用来生成迭代器.

    • next(iterator[, default])返回迭代器的下一个项目. 在元素为空时返回默认值, 若没有则会触发StopIteration异常. 在元组推导式和next中使用过, 不过是下面的『生成器』.

    把一个类作为一个迭代器使用需要在类中实现两个魔法方法__iter__()__next__().

    • __iter__(self)定义当迭代容器中的元素的行为, 返回一个特殊的迭代器对象, 这个迭代器对象实现了__next__()方法并通过StopIteration异常标识迭代的完成.

    • __next__()返回下一个迭代器对象.

      • StopIteration异常用于标识迭代的完成,防止出现无限循环的情况,在__next__()方法中我们可以设置在完成指定循环次数后触发StopIteration异常来结束迭代。

    classFibs:def__init__(self,n=10):self.a=0self.b=1self.n=ndef__iter__(self):returnselfdef__next__(self):self.a,self.b=self.b,self.a+self.bifself.a>self.n:raiseStopIterationreturnself.afibs=Fibs(100)foreachinfibs:print(each,end='')#1123581321345589

    生成器

    在 Python 中,使用了yield的函数被称为生成器(generator)。

    • 跟普通函数不同的是, 生成器是一个返回迭代器的函数, 只能用于迭代操作, 更简单点理解生成器就是一个迭代器.

    • 在调用生成器运行的过程中, 每次遇到yield时函数会暂停并保存当前所有的运行信息, 返回yield的值, 并在下一次执行next()方法时从当前位置继续运行.

    • 调用一个生成器函数, 返回的是一个迭代器对象.

    deflibs(n):a=0b=1whileTrue:a,b=b,a+bifa>n:returnyieldaforeachinlibs(100):print(each,end='')#1123581321345589

    到此,关于“python函数和面向对象实例分析”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注恰卡编程网网站,小编会继续努力为大家带来更多实用的文章!

    发布于 2022-02-15 20:42:01
    收藏
    分享
    海报
    0 条评论
    34
    上一篇:mysql数据库中Decimal类型怎么使用 下一篇:ASP.NET Core Zero模块系统的示例分析
    目录

      0 条评论

      本站已关闭游客评论,请登录或者注册后再评论吧~

      忘记密码?

      图形验证码