Python自定义函数和类

Python模块的功能主要是由模块和类来实现,除了调用已有的模块的函数和类,还可以自定义函数和类。

文章目录

    • 1、自定义函数
      • 1.命名函数
      • 2.匿名函数
    • 2、自定义类
      • 1.类的创建和实例化对象
      • 2.类的继承
    • 3、函数和类的组织

1、自定义函数

函数可以被其他代码调用,函数在调用时可通过参数传递返回一个结果对象。利用函数一方面可以使代码重用,另一方面可以对复杂的程序进行任务分解。

1.命名函数

命名函数即有名称的函数,大多数函数都是命名函数。python中的def语句用于定义命名函数。
函数对象有一个 __doc__属性,通常存放函数的简单操作说明信息,在定义函数声明后第一个没有赋值的字符串将作为函数的__doc__属性值,也可以直接对其进行赋值。

函数的参数有两种类型:位置参数关键字参数。位置参数更具参数的位置顺序进行匹配,没有缺省值;关键字参数以关键字匹配参数,可以定义缺省值。 位置参数严格按位置顺序进行匹配,而关键字参数可以不按位置顺序匹配,因此位置参数必须放在关键字参数之前,否则会造成匹配错误。
例(创建一个计算列表中数字元素之和的函数)

def total(values, start=0, end=None):
    if end is None:
        end = len(values)
    result = 0
    for i in range(start, end):
        result = result + values[i]
    return result


a = [20, 30, 60]
print(total(a))  # 输出110
print(total(a, 2))  # 输出60
print(total(a, end=2))  # 输出50

2.匿名函数

Python用lambda关键词创建匿名函数,它是通过参数以及参数表达式表示函数。
lambda函数定义的是单行函数,可以有多个参数,表达式只有一条。
例(计算两数和的平方的匿名函数)

b = (lambda x, y: (x + y)**2)(2, 3)
print(b)  # 输出25,即(2+3)的平方

如果匿名函数需要被其他语句调用,可以把匿名函数赋给一个变量,即产生一个命名函数:

c = (lambda x, y: (x + y) ** 2)
c(3, 3)  # 返回值为36

lambda函数经常和map、filter、sorted等函数结合使用。Python2.x中map函数和filter函数直接返回列表,而在Python3.x,map函数返回map对象,filter函数返回filter对象(都需循环输出迭代结果),可利用list()函数转换成列表。

与map函数结合是将lambda函数应用于给定序列的所有元素:

list(map((lambda x: x*100+x**2), [10, 2.5, 3]))  
# 返回值为[1100, 256.25, 309]

与filter函数结合是用lambda函数计算序列中的所有元素的布尔值,在此基础上返回值为True的元素:

list(filter((lambda x: x > 10), [1, 3, 10, 30, 50]))
# 返回值为[30, 50]

与sorted函数的结合是利用lambda函数选择用于排序的键(key),在此基础上,返回排序后的序列:

sorted([["b", 3], ["a", 5], ["c", 1]], key=(lambda x: x[1]))
# 返回值为[['c', 1], ['b', 3], ['a', 5]]

2、自定义类

类实际上就是数据类型,Python是面向对象的编程语言,支持创建类及根据类产生实例。

1.类的创建和实例化对象

class < classname > (superclass):
    代码块

class语句是一个复合语句,classname为类名,superclass主要是继承的超类。新建的类具有所继承的类的所有属性和方法。所有类都继承基本类(object类),即缺省superclass的情况下创建的类也具有基本类的属性和方法。
基本类的主要属性:

_doc_  类的文档字符串(说明)
_dict_  类字典(属性和值)
_module_  类所在的模块
_class_  类所在的类

基本类的主要方法

__init__(self)  构造器,定义特殊方法
__del__(self)  解构器,清除对象
__setattr__(self,attr,val)  设置属性值
__getattribute__(self,attr)  获取属性值
__delattr__(self,attr)  删除属

在新建类对象时,可以利用赋值语句定义新的属性,利用函数定义新的方法。需注意的是class语句中的函数,必须有一个self参数(且为第一个),self参数指实例对象。
例(创建一个PointTest类):

class PointTest:
    """this is a class for point"""
    ID = "0"
    x = 0
    y = 0

    def move(self, dx, dy):
        x = self.x + dx
        y = self.y + dy
        self.x = x
        self.y = y

创建PointTest类后,实例化一个PointTest类对象(p1)并进行相关操作:

p1 = PointTest()
print(p1.ID, p1.x, p1.y)  # 输出为0 0 0
p1.ID = 1
p1.move(2, 2)
print(p1.ID, p1.x, p1.y)  # 输出为1 2 2



所有类都有一个__ init __方法,这个方法在实例化一个对象时就好执行,用于初始化对象,如果没有定义则按默认方法处理。
如要在创建实例时具有某些属性值(即传递参数),可在 __ init __方法中定义传入参数。如:

class PointTest:
    """this is a class for point"""
    def __init__(self, ID, x, y):
        self.ID = ID 
        self.x = x
        self.y = y

    def move(self, dx, dy):
        x = self.x + dx
        y = self.y + dy
        self.x = x
        self.y = y

这样利用下面语句就可以实例化一个指定的ID、x、y的PointTest:

p1 = PointTest("1", 3, 3)

2.类的继承

子类继承超类的属性和方法,如果子类新建了相同的名称的属性和方法,就会覆盖超类的属性和方法,即重写相同名称的属性和方法。
例(创建一个POI类继承上面的PonitTest类,并重写其__ init __方法):

class POI(PointTest):
    def __init__(self, name="test"):
        self.name = name

此时,实例化一个POI对象POI1,该对象将只有name属性,没有超类的ID等属性:

POI1 = POI()
print(POI1.name)  # 运行输出:test
print(POI1.ID) 
# 运行将报错AttributeError: 'POI' object has no attribute 'ID'

如果需要同时调用超类的__init__方法,可以在创建类此方法时增加一条语句,如下:

class POI(PointTest):
    def __init__(self, name="test"):
        super().__init__()  # 该语句将执行所有超类的__init__方法
        self.name = name

3、函数和类的组织

1.创建模块
相关的函数和可以组织在一个模块中,被其他模块中的语句所调用。创建模块就是创建一个扩展名为py的文件,把相关的函数和类放在同一个文件中。
2.创建包
包(package)是一个有层次的文件目录结构,由子包、模块及其它相关文件组成。要创建包,首先就是新建一个文件夹,文件夹名即为包名,然后在文件夹中创建一个__init__.py文件(可以是一个空文件,也可以添加一些包的初始化信息)作为包的标识,然后在文件夹里添加子包、模块及其它文件。
3.包的发布
包的发布实际上是把包中的内容打包到一个压缩包中或创建为一个exe文件,成为一个安装文件,供他人安装使用。包的发布有两种形式:源码发布和编译发布。
(具体就暂时不做说明了,仅作了解记录。)

你可能感兴趣的:(Python,python)