Python快速入门(二)函数与对象

本文详细介绍了Python中的函数,包括定义、作用域、深浅复制、lambda表达式和eval()函数。同时,讲解了类的概念,如实例化、类方法、静态方法、__call__方法以及属性装饰器,并探讨了继承和单例模式。内容涵盖了Python面向对象编程的基础知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.函数

语法

def 函数名 ([参数列表]) :
‘’‘文档字符串’‘’
函数体/若干语句

要点

1.我们使用def来定义函数,然后就是一个空格和函数名称;
(1)Python执行def时,会创建一个函数对象,并绑定到函数名变量上。

2.参数列表
(1)圆括号内是形式参数列表,有多个参数则使用逗号隔开
(2)形式参数不需要声明类型,也不需要指定函数返回值类型
(3)无参数,也必须保留空的圆括号
(4)实参列表必须与形参列表一一对应

3.return返回值
(1)如果函数体中包含return语句,则结束函数执行并返回值;
(2)如果函数体中不包含return语句,则返回None值。

4.调用函数之前,必须要先定义函数,即先调用def创建函数对象
(1)内置函数对象会自动创建
(2)标准库和第三方库函数,通过import导入模块时,会执行模块中的def语句

特性

函数的复制

函数也是对象,函数不带圆括号时作为对象处理,这意味着函数也可以浅复制,例如

zhengshu = int
zhengshu("234")

此时zhengshu()等同于int()

作用域

函数内部变量为局部变量,如有必要,须要用global关键字声明以操作全局变量

m=1
def func():
    global m
    m = 0
    return 1
func()
print(m)
#输出0

m=1
def func():
    m = 0
    return 1
func()
print(m)
#输出1

m=1
def func():
    global m
    global n
    n=m
    return 1
func()
print(n)
#输出1

深复制与浅复制

Python的深复制和浅复制有一个很简单的调用方法

import copy

b=copy.copy(a)
b=copy.deepcopy(a)

lambda表达式和匿名函数

lambda表达式可以用来声明匿名函数。lambda函数是一种简单的、在同一行中定义函数的方法。lambda函数实际生成了一个函数对象。

lambda表达式只允许包含一个表达式,不能包含复杂语句,该表达式的计算结果就是函数的返回值。

lambda表达式的基本语法如下:

lambda arg1,arg2,arg3… : <表达式>

arg1/arg2/arg3为函数的参数。<表达式>相当于函数体。运算结果是:表达式的运算结果。

f=lambda a,b,c:print(a+b-c)
f(1,2,3)

(lambda a,b,c:print(a+b-c))(1,2,3)

eval()函数

功能:将字符串str当成有效的表达式来求值并返回计算结果。

语法: eval(source[, globals[, locals]]) -> value

参数:

​ source:一个Python表达式或函数compile()返回的代码对象

​ globals:可选。必须是dictionary

​ locals:可选。任意映射对象

实例

a = 1
b = 2
print(eval('a+b'))
#输出:3
print(eval('a+b', {'a': 1, 'b': 2}))
#输出:3

nonlocal关键字

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

global 用来声明全局变量。

LEGB规则

Python在查找“名称”时,是按照LEGB规则查找的:

Local–>Enclosed–>Global–>Built in

Local 指的就是函数或者类的方法内部

Enclosed 指的是嵌套函数(一个函数包裹另一个函数,闭包)

Global 指的是模块中的全局变量

Built in 指的是Python为自己保留的特殊名称。

如果某个name映射在局部(local)命名空间中没有找到,接下来就会在闭包作用域(enclosed)进行搜索,如果闭包作用域也没有找到,Python就会到全局(global)命名空间中进行查找,最后会在内建(built-in)命名空间搜索 (如果一个名称在所有命名空间中都没有找到,就会产生一个NameError)。

参数

默认值参数

我们可以为某些参数设置默认值,这样这些参数在传递时就是可选的。称为“默认值参数”。默认值参数放到位置参数后面。例如:

def func(r=10):
    for temp in range(r):
        print(temp, end=' ')
    return 22


print(func())
#输出 0 1 2 3 4 5 6 7 8 9 22

位置参数

函数调用时,实参默认按位置顺序传递,需要个数和形参匹配。按位置传递的参数,称为:“位置参数”。实际上就是其他语言的参数。

命名参数

我们也可以按照形参的名称传递参数,称为“命名参数”,也称“关键字参数”。例如:

def func(name,age,job):
    print((name,age,job))

func(1,2,3)
func(age=2,job=3,name=1)

输出

(1, 2, 3)
(1, 2, 3)

可变参数

可变参数指的是“可变数量的参数”。分两种情况:

  1. *param(一个星号),将多个参数收集到一个“元组”对象中。

  2. **param(两个星号),将多个参数收集到一个“字典”对象中。

例如:

def func(a, b, *c):
    print(a, b, c)

func(1, 2, 3, 4, 5, 6)
#1 2 (3, 4, 5, 6)
def func(a, b, **c):
    print(a, b, c)

func(1, 2, m=1, n=2)

#1 2 {'m': 1, 'n': 2}

强制命名参数

在带星号的“可变参数”后面增加新的参数,必须在调用的时候“强制命名参数”。

2.类对象

定义与实例化

class Person:
    def __init__(self, name, age):#构造函数
        self.name = name
        self.age = age

    def getName(self):
        return self.name

    def getAge(self):
        return self.age


p0 = Person("张三", 22)#实例化

new()方法: 用于创建对象,但我们一般无需重定义该方法。
如果我们不定义__init__方法,系统会提供一个默认的__init__方法。如果我们定义了带参的__init__方法,系统不创建默认的__init__方法。

相关函数

dir(obj)#获得对象的所有属性、方法
obj.__dict__ #获取对象的属性字典
pass #空语句
isinstance(对象,类型)  #判断“对象”是不是“指定类型”

类方法

类方法是从属于“类对象”的方法。类方法通过装饰器@classmethod来定义,格式如下:

@classmethod
def  类方法名(cls  [,形参列表]) :
	函数体

要点如下:
1.类方法对类属性的操作会导致类的属性彻底改变,之后实例化的对象携带的也都是修改后的属性值
2.第一个cls必须有;cls指的就是“类对象”本身;self则指的是实例化对象
3.调用类方法格式:“类名.类方法名(参数列表)”。 参数列表中,不需要也不能给cls传值。
4.类方法中访问实例属性和实例方法会导致错误
5.子类继承父类方法时,传入cls是子类对象,而非父类对象

静态方法

Python中允许定义与“类对象”无关的方法,称为“静态方法”。

“静态方法”和在模块中定义普通函数没有区别,只不过“静态方法”放到了“类的名字空间里面”,需要通过“类调用”。

静态方法通过装饰器@staticmethod来定义,格式如下:

@staticmethod
def  静态方法名([形参列表]) :
	函数体

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

__call__方法和可调用对象

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

class cal:
    def __init__(self):
        pass

    def __call__(self, a, b):
        return a + b


c = cal()
print(c(1, 2))
#输出为3

@property装饰器

该方法用于支持把方法以属性的方式调用,可以方便的把属性封装

注意:此时属性的get和set方法必须同名,否则报错!

'''简单的员工工资修改限制,如果是涨薪,则修改生效;如果是降薪,则修改不生效'''
class employee:
    __company = 'cpt'

    def __init__(self, name, sal):
        self.name = name
        self.__salary = sal

    @property
    def salary(self):
        return self.__salary

    @salary.setter
    def salary(self, newSal):
        if newSal > self.__salary:
            self.__salary = newSal
            print("新工资:" + str(self.__salary))


e = employee('张三', 10000)
print(dir(e))
print(e.salary)
e.salary=9
print(e.salary)
e.salary=900000
print(e.salary)

重载

截止到2023.01.17,Python版本3.10,不支持方法的重载

添加/修改方法

修改方法

class cal:
    def __init__(self):
        pass

    def 加法(self, a, b):
        return a + b


c=cal()
print(c.加法(1,2))
def 乘法(self,a,b):
    return a*b
cal.加法=乘法
print(c.加法(3,4))

输出为

3
12

添加方法:

class cal:
    def __init__(self):
        pass

    def 加法(self, a, b):
        return a + b


c=cal()
print(c.加法(1,2))
def 乘法(self,a,b):
    return a*b
cal.乘法=乘法
print(c.加法(3,4))
print(c.乘法(3,4))

输出为

3
7
12

私有属性和私有方法(实现非严格封装)

Python对于类的成员没有严格的访问控制限制,这与其他面向对象语言有区别。关于私有属性和私有方法,有如下要点:

  1. 通常我们约定,两个下划线开头的属性是私有的(private)。其他为公共的(public)。

  2. 类内部可以访问私有属性(方法)

  3. 类外部不能直接访问私有属性(方法)

  4. 类外部可以通过“对象命._类名__私有属性(方法)名”访问私有属性(方法)

继承

语法

class  子类类名(父类1[,父类2...]):
	类体

*子类并不会自动调用父类的__init__(),我们必须显式的调用它。

*子类自动继承成员,如有需要可直接覆写

*子类调用父类方法,可使用super关键字

mro()方法与__MRO__属性(查看类继承层次)

实例:

class Person:
    race = "animal"

    def __init__(self, name, age):
        self.name = name
        self.age = age


class Student(Person):
    race = "Person"


print(Student.mro())
print(Student.__mro__)

单例模式

实例:

class Tool:
    instance = None

    def __init__(self):
        self.name = "Tool"
        self.age = 0

    def test(self):
        print("-------------------------test---------------------")

    def __new__(cls, *args, **kwargs):
        if cls.instance == None:
            cls.instance=super(Tool, cls).__new__(cls)
        return cls.instance


t = Tool()
t1 = Tool()
t2 = Tool()
print(id(t))
print(id(t1))
print(id(t2))
print(t,t1,t2)
t.test()
t1.test()
t2.test()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值