Python -- 函数(def)与面向对象思维

这篇博客探讨了Python编程中的函数定义、局部与全局变量的使用、递归调用以及字符串、列表、元组、集合和字典等数据结构的应用。作者强调了面向对象编程的思想,解释了类的定义、方法以及如何通过类来实现行为抽象。通过实例,如阶乘、回文字符串检查、双色球随机投注和数字时钟,深入浅出地展示了Python编程的技巧和概念。

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

一、定义函数:

 1.我们可以把程序中相对独立的功能模块抽取出来
 2.这样做的好处一是减少重复代码的编写
 3.二是将来可以重复的使用这些功能模块
 4.Python中的函数就是代表了这样的功能模块
1. 就以定义阶乘的函数而言,简洁明了,不需要重复的去写同一段代码。
例1:阶乘函数的定义
def f(n):
    y = 1
    for x in range(1,n+1):
        y *= x
    return y
2.调用函数,先将最小公倍数的函数写出来,那么求最大公约数的时候直接调用最小公倍数的函数就可以得到。
例2:最小公倍数与最大公约数
# 最小公倍数
def gcd(x,y):
    (x,y) = (y,x) if x > y else (x,y)
    for fac in range(x,0,-1):
        if x % fac == 0 and y % fac == 0:
            return fac
# 最大公约数
def lcm(x,y):
    return x * y // g(x,y)
3.利用字符串下标,取得各个元素进行比较,获得想要的结果,比如回文字符串
例3:回文字符串 例如’客上天然居居然天上客;僧游云隐寺寺隐云游僧’
def is_huiwen(a):
    b = len(a)
    for n in range(int(b/2)):
        if a[n] == a[b-1]:
            return True
a = input('请输入:')
if is_huiwen(a):
    print('%s是回文字符串'%a)
else:
    print('%s不是回文字符串'%a)
二、局部变量与全局变量,尽量减少对全局变量的使用
1.python 搜索一个变量的方式是从局部作用域到嵌套作用域再到全局作用域 Local - Enclosed - Global
def f():
    # 函数内的局部变量,离开f()函数变量a是无法访问的
    # local variable
    global(a)   # 局部变量中执行全局变量
    a = 200
    print(a)
2.函数的递归调用,递归是一种思想,一种每次变化都与本身相关。那么要写出递归函数就必须有下列条件:
1).收敛条件 - 让递归在有限的次数内完成或者回溯
2).如果递归无法在有限次数内收敛有可能导致RecursionError
3).递归公式
例4:100以内的累加,这就是典型的递归函数:
def f(n):
    if n == 1:
        return 1
    return n + f(n-1)
if __name__ = 'main':
    # 在进入函数调用之前要保存当前的执行现场
    # 函数的执行现场是保存在一种称为栈(stack)的内存空间上
    # 栈是一种先进后出(FILO)的存储机构
    f(100)
3.字符串的相关应用 ,字符串类型,字符串的各种转换与下标运算及切片
例5:在命令窗口运行可以形成跑马灯的效果
import time
import os


def main():
    a = '欢迎来到我的世界~~~'
    while True:
        os.system('cls')
        print(a)
        time.sleep(0.5)
        a = a[1:] + a[0]


if __name__ == '__main__':
    main()
三、定义可变参数,参数可变,可以是一个或多个;当定义函数时,需要写注释,让人明白这段函数想要达到的目的是什么,方便将来调用。
例6:以累加为例,参数个数可以给任意个,都能累加得到结果
def add(*args):
        """
定义可变参数,累加
    :param args: 可变参数
    :return: 累加求和后的值
    """
    total = 0
    for val in args:
        total += val
    return  total


if __name__ == '__main__':
    print(add(12,3,45))
四、列表的应用,有了列表(容器),就可以用一个变量去保存多个数据;也可以使用循环,对列表内的保存的数据进行操作,运用for in循环对列表内的数据进行遍历。
for index, val in enumerate(g): #enumerate 既有下标也有值
    print(index, ':', val)
1. Python内置的排序方法默认都是升序(从小到大)
2.如果希望排列成降序(从大到小)可以通过reverse参数来指定
3.Python中的函数几乎都是没有副作用的函数
4. 调用函数之后,不会影响传入的函数
例7:生成器与生成式:
f = [x ** x for x in range(1,100)]
# 用列表的生成表达式语法创建列表容器
# 用这种语法创建列表之后元素已经准备就绪所以需要耗费较多的内存空间
print(sys.getsizeof(f))    #   占用多少内存空间
print(f)
f = (x ** x for x in range(1, 100))# 生成器
# 列表生成器 这里得到的不是一个列表 而是一个生成器对象
# 通过生成器可以获得数据 它不占用额外的 空间存储数据
# 每次需要数据的时候就通过生成器取数据 当然这需要花时间
print(f)
5. yeild 函数变为生成器~
例8:斐波拉切数列生成器:
def fib(n):
    a,b =0 ,1
    for _ in range(n):
        a, b = b, a + b
        yield a       
五、栈与堆,变量与对象
1.栈(stack) 堆(heop) 静态区
2.变量 - 是对对象的引用 -其实变量里面放的是对象的地址- 在栈上
3.对象 - 在堆上- 为了获取更大的存储空间
4.id()函数和is运算符 - 验证身份
例9:列表的综合运用,双色球的随机投注:
from random import randrange
def display(balls):
    for index,ball in enumerate(balls):
        if index == len(balls) - 1:
            print('|',end = ' ')
        print('%02d'%ball,end=' ')
    print()

def select_balls():
    red_balls = [x for x in range(1,34)]
    select_balls = []
    for _ in range(6):
        index = randrange(len(red_balls))
        select_balls.append(red_balls[index])
        del red_balls[index]
    select_balls.sort()
    select_balls.append(randrange(1,16))
    return select_balls

def main():
    n = int(input('机选几柱:'))
    for _ in range(n):
        display(select_balls())
if __name__ == '__main__':
    main()
注:此处双色球例子还用到了1.for index,ball in enumerate(balls):,使得在使用的时候,既可以取到该列表的下标,也可以取到对应的值;2.randrange(a,b),取值范围为【a,b】,而range(a,b)的取值范围则是【a,b);3.del 清除列表中的某一值,据给的下标而定
五、元组,集合与字典
1.元组:tuple 如(a,b,c,c,b,a)
2.集合:set 如 {a,b,c} 集合内无重复元素
3. 字典:dict 如 {‘a’:’1’,’b’:’2’:’c’:’3’}
2.1 集合可以求交集 set1.intersection(set2)、“&” ;并集 set1.union(set2) “|” ;差集 set2.difference(set1) “-” ;超集 set1.symmetric_difference(set2) “^”
1).print(set2.issubset(set1)) #判断set1是否为set2的子集
等同于print(set2 > set1)
2).print(set2.issuperset(set1)) # 判断set1是否为set2的超集
等同于print(set1 > set2)
例10:录入成绩
def main():
    names = ['张飞','刘备','关羽','吕布','貂蝉']
    subjects = ['语文','数学','Python']
    scores = [[0 for _ in range(3)] for _ in range(5)]
    for row,name in enumerate(names):
        print('请输入%s的成绩'%name)
        for col,subject in enumerate(subjects):
            scores[row][col] = int(input(subject + ':'))
    print(scores)
if __name__ == '__main__':
    main()
小结:这里录入成绩建立scores,就如同画个表格一样,5排代表有5个人,3列代表有3门课,依次需要填入各个人及各门课的成绩,所以这样建立了scores列表[[0 for _ in range(3)] for _ in range(5)],这里需要注意的是,不能直接像[[0] * 3] * 5这样,乘以数字,这会代表都是调用同一地址的内容,最后成绩只会出一组,每次更新都会顶替之前的成绩。

六、如何用面向对象的思维写程序:

1.定义类
类是对象的蓝图和模板,有了类就可以创建对象
定义类需要做两件事情:数据抽象和行为抽象
数据抽象 - 抽取对象共同的静态特征(找名词) - 属性
行为抽象 - 抽取对象共同的动态特征(找动词) - 方法
定义类的关键字 - class- 类名(每个单词首字母大写)
2.方法
我们定义一个方法就代表对象可以接收这个消息
对象的方法的第一个参数都是统一写成self
它代表了接收消息的对象 - 对象.消息(参数)
3.行为
给对象发出消息
通过给对象发消息堂对象完成某些工作
解决任何问题都是通过让对象去做事情
4.另外:
我们定义一个类实际上是把数据和操作数据的函数绑定到一起
形成一个逻辑上的整体 这个整体就叫做对象
而且将来任何时候想使用这种对象时直接复用这个类型
5.用具体的例子来说明:
例11:数字时钟:(如00:00:00一样,每隔1秒+1,如同真的时钟一样)
import time


class Clock(object):  # 这里Clcck首字母大写。类的名字。   一般括号内会写object。
    def __init__(self, hour=0, minute=0, second=0):  # 这里是构造方法。
        self._hour = hour  # 这里是给对象绑定属性  _hour 加一个下划线是代表次=此属性受保护,不能更改
        self._minute = minute
        self._second = second

    def run(self):
        self._second += 1
        if self._second == 60:
            self._second = 0
            self._minute += 1
            if self._minute == 60:
                self._minute = 0
                self._hour += 1
                if self._hour == 24:
                    self._hour = 0

    def __str__(self):  # 下面的方法__str__(self)可以获得对象的字符串表达形式,当我们用print打印对象时会自动调用该方法
        return ('%02d:%02d:%02d' % (self._hour, self._minute, self._second))

def main():
    clc = Clock()
    while True:
        print(clc)
        time.sleep(1)
        clc.run()


if __name__ == '__main__':
    main()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值