Python —— 简单知识(二)

本文详细介绍了Python中的函数,包括定义、调用、参数、返回值、全局与局部变量、函数嵌套、元组拆包与组包、默认参数、关键字参数、不定长参数。此外,还讲解了可变与不可变类型、递归函数、匿名函数(lambda)、列表推导式、文件读写、面向对象概念,如类、对象、继承、私有权限及多态等核心概念。

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

1. 函数

           1. 函数的作用 : 保存某段程序.某个代码片段.提升代码的可读性,让代码复用。

           2. 函数使用包含两个步骤:

                      1.定义函数 ----在函数中编写代码,实现功能

                                           def  函数名():

                                                   函数封装的代码

                      2.调用函数 ----执行编写的代码

                                           函数名()

           >>> def test(a,b):
           ...     "用来完成对2个数求和"
           ...     print("%d"%(a+b))
           ... 
           >>> 
           >>> test(11,22)
           33

           3. 函数的参数

                  1.在定义函数后面的小括号中写的叫参数(形参).

                  2.形数就是给将调用函数的真实数据作占位.

                  3.函数调用时,里面写的数据叫真实数据(实参)

                  4.如果函数设置了参数,在调用函数时必须传对应的真实数据.

          4.全局变量和局部变量     

                 # 全局变量:在函数外面定义的所用人都能使用

                 # 全局变量作用于整个代码,最好不要和形参同名.

                 # 形参的作用域(可使用的范围)     只能函数内部

          # 函数内部定义

                # 不同函数的形参名可以是同名的,相互不影响.

               # 在函数内部 可以使用global 关键字 定义全局变量    

     # 可以使用一次global对多个全局变量进行声明
     global a, b
     # 还可以用多次global声明都是可以的
     # global a
     # global b

          5. 函数的返回值 -- return

                     返回值----把函数的执行结果返回出来,(如果需要使用执行结果,就返回它,赋值给一个变量)

              

                    #个函数中可以有多个return语句,但是只要有return语句被执,那么这个函数就会结束

                    # return后面可以是元组,列表、字典等,只要是能够存储多个数据的类型,就可以一次性返回多个数据

      def function():
          # return [1, 2, 3]
          # return (1, 2, 3)
          return {"num1": 1, "num2": 2, "num3": 3}

                     ## 如果return后面有多个数据,那么默认是元组

                     #如果使用多个变量接收返回值,python会自动将元组拆包成单个数据.

                     # 返回值两个作用:1.把结果返回出去 2.终止下面程序的运行

           6.  函数的嵌套调用      

                      一个函数里面调用了另一个函数

           7. 元祖的拆包和组包

                      解包也叫拆包 —— 把元组分解开     多个元组对应多个变量,就能解包

                      自动组包 —— 自动组合成 元组      一个变量,对应多个值,就会自动组包

# 组包 与 解包
a = 1, 2, 3
print(a)  # (1, 2, 3)

x, y, z = a
print(x, y, z)  # 1 2 3

           8. 函数参数

                   1) 缺省参数(默认参数)   

        def printinfo(name, age=35):
            print(.....)

         如果 age 没有被传入,会打印默认的 age

                       # 总结: 在形参中默认有值的参数,称之为缺省参数;

                                      缺省参数都写在最后面,可以被传参所改变。

                    2) 关键字参数:  不管形参顺序,都能正确传参,自动去找形参进行赋值 

                                                (函数调用使用关键字参数来确定传入的参数值。)

           def printme( str ):
               "打印任何传入的字符串"
              print str;
              return;
 
           #调用printme函数
           printme( str = "My string");

                    3)不定长参数 :

                                    *args  随便你传多少个参数,输出默认都是元组格式;

                                    **kwargs  转门接收未定义形参的关键字参数,把他们变成字典.

                     # 注意:  如果很多个值都是不定长参数,那么这种情况下,可以将缺省参数放到 *args的后面, 但如果有**kwargs的话,**kwargs必须是最后的

# # 函数的参数传递
def fun2(a, *args, b=5, **kwargs):
    print('参数:{}, {}'.format(a, b))
    x, y = args
    print(args)
    print(x, y)
    print(kwargs)
    dic = kwargs
    for i in dic.values():
        print(i)


fun2(2, 3, 4, b=9, d='dd', g='il')


## output
参数:2, 9
(3, 4)
3 4
{'d': 'dd', 'g': 'il'}
dd
il

         

           9. 可变、不可变类型               

                   可变类型有: 列表、字典、集合               (修改时,内存地址不发生那个改变)

                   不可变类型有: 数字、字符串、元组          (修改时,内存地址发生改变)

           10.  递归函数                   

                         如果一个函数在内部不调用其它的函数,而是自己本身的话,这个函数就是递归函数

           11. 匿名函数

                        没有名字的函数,只能返回一个结果。相当于函数的简写方法。

                                 #  fun1=  lambda 参数1,参数2 :返回值(需要得到的表达式或者值)
                                >>> fun1=lambda a,b : a+b
                                 >>> fun1(2,3)
                                         5

            12. 列表推导式 -- 轻量级循环创建列表

                     list1 = [把每一次循环过后的值,赋值到这 for 变量名 in 循环的次数] 
                     #生成一个 0-100的列表   list1 = [a for a in range(101)]

             13.  文件的读写

                       1) 写数据 write                   

              f = open('test.txt', 'w')
              f.write('hello world, i am here!')
              f.close()

                               简单写法: with open("test.txt","w") as f:

                                                         f.write('hello world')

                      2)  读取方式 :

       read(5)    一个一个字的进行读取,如果读大文件比较费劲, 可添加读取位数.

       readlines()  一行一行读取,把每一行变成一个列表中的数据.如果想得到每一行,可用遍历把数据都输出来. (自带有\n(换行符))

       readline()    默认只读一行数据,加循环可以重复读取多行数据.

       ###     读大文件时:读取多行用 .readlines()      只读一行用 .readline()

r	以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
w	打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a	打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。

r+	打开一个文件用于读写。文件指针将会放在文件的开头。没有该文件会报错
w+	打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a+	打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。


# # 文件的写入
# with open('test01.txt', "w") as f:
#     f.write('hello')

#  文件的读取
# with open('test01.txt', 'r') as f:
#     print(f.read(3))

# 文件的追加
with open('test01.txt', 'a') as f:
    f.write('\n world')

          14.  面向对象 

                一:类 :描述共同行为的集合。

                            #类是总结事物特征的抽象概念,而对象是具体存在的某个实物

                   定义类                      class  类名      (类名一般使用大驼峰) 

                                                    def  eat(self)     方法。定义对象的共同行为。(会自动添加第一个形参self)

                   创建对象             dog1 = Dog()     # 用类创建对象  格式: 对象名= 类名()

                                               dog1.eat()       # 调用对象的方法   格式:   对象名.方法()

class Dog(object):    # 定义一个类  类名 的命名规则按照"大驼峰命名法"
    def __init__(self, name):   # 初始化方法
        self.name = name

    def __str__(self):
        return "{}是一条非常友好的狗狗".format(self.name)

    def eat(self):    # 类里面的 实例方法
        print('喜欢吃肉')

dog1 = Dog("小黄")    # 创建对象
dog1.eat()           # 调用类的用实例方法
print(dog1.name)     #小黄

print(dog1)          # 小黄是一条非常友好的狗狗(有魔法方法__str__ ,打印对象会调用 str方法)

                 

                self 关键字

                           1.self 表示当前调用该方法的对象

                           2.在方法中使用对象的属性时,用self来访问,不要直接去用对象访问.

                           3.Python解释器会隐式的将调用方法的对象作为第一个实参进行传递.

                     对象  包括: 1)属性      用于记录与对象相关的数据

                                       2)方法      用于实现与对象相关的操作

        例子 :

class Hero(object):  # 新式类定义形式
    """info 是一个实例方法,类对象可以调用实例方法,实例方法的第一个参数一定是self"""
    def info(self):
        """当对象调用实例方法时,Python会自动将对象本身的引用做为参数,
            传递到实例方法的第一个参数self里"""
        print(self) 
        print("self各不同,对象是出处。")


# Hero这个类 实例化了一个对象  taidamier(泰达米尔)
taidamier = Hero()

# 对象调用实例方法info(),执行info()里的代码
# . 表示选择属性或者方法
taidamier.info()

print(taidamier)  # 打印对象,则默认打印对象在内存的地址,结果等同于info里的print(self)
print(id(taidamier))  # id(taidamier) 则是内存地址的十进制形式表示

# 如果有 __str__ 方法: print(对象)或类里面的 print(self) 会走 str 里面的方法 

             二 : 有参数的 __init__() 方法:

class Hero(object):
    """定义了一个英雄类,可以移动和攻击"""

    def __init__(self, name, skill, hp, atk, armor):
        """ __init__() 方法,用来做变量初始化 或 赋值 操作"""
        # 英雄名
        self.name = name
        # 技能
        self.skill = skill
        # 生命值:
        self.hp = hp
        # 攻击力
        self.atk = atk
        # 护甲值
        self.armor = armor

    def move(self):
        """实例方法"""
        print("%s 正在前往事发地点..." % self.name)

    def attack(self):
        """实例方法"""
        print("发出了一招强力的%s..." % self.skill)

    def info(self):
        print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
        print("英雄 %s 的攻击力 :%d" % (self.name, self.atk))
        print("英雄 %s 的护甲值 :%d" % (self.name, self.armor))


# 实例化英雄对象时,参数会传递到对象的__init__()方法里
taidamier = Hero("泰达米尔", "旋风斩", 2600, 450, 200)
gailun = Hero("盖伦", "大宝剑", 4200, 260, 400)


# print(gailun)
# print(taidamier)

# 不同对象的属性值的单独保存
print(id(taidamier.name)) 
print(id(gailun.name))

# 同一个类的不同对象,实例方法共享
print(id(taidamier.move())) 
print(id(gailun.move()))

## 不同对象的属性值的单独保存;实例方法共享

 ## 1. 通过一个类,可以创建多个对象;

      2.       __init__(self)中,默认有1个参数名字为self,如果在创建对象时传递了2个实参,那么__init__(self)中出 self作为第一个形参外还需要2个形参,例如__init__(self,x,y)

  3. 在类的内部获取 属性 和实例方法,通过 self 获取;

  4. 在类外部获取 属性 和实例方法,通过对象名获取;

  5. 如果一个类有多个对象,每个对象的属性是各自保存的,都有各自独立的地址;  

  6. 但是实例方法是所有对象共享的,只占用一份内存空间。类会通过self来判断是哪个对象调用了实例方法。

       三.  魔法方法: __单词__(self)      不需要调用,在特殊情况下自动调用

          __init__        当对象创建时会自动调用,init定义的参数,是在创建对象的小括号中传递.

          __str__        直接打印对象时,会被自动调用,里面必须写return,必须要返回字符串   (如果没有 __str__ 则默认打印 对象在内存得地址).

         __del__       当对象被销毁前,会被自动调用

       四. 继承: 简化代码;只要是继承了,那么就能够得到父类的所有的方法和属性。

           ## 1.   创建类的时,python 默认就会帮你去继承 object;  object 叫作 基类。

           ## 2.   语法格式 :  class子类名(写上要继承的类/父类)

          ## 3.    B类如果继承了A类,那么A类就是B类的父类/基类,反之,B是A的子类.

                      (一个类,可以同时继承多个类;优先继承第一个类)

# 父类
class A(object):
    def __init__(self):
        self.num = 10

    def print_num(self):
        print(self.num + 10)
# 子类
class B(A):
    pass

b = B()              #  创建子类对象
print(b.num)         #  子类对象调用父类的属性
b.print_num()        #  子类对象调用父类的方法

# mro 查看继承关系
print(B.__mro__)         (<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

## 1. 多继承可以继承多个父类,也继承了所有父类的属性和方法

      2. 如果多个父类中有同名的 属性和方法,则默认使用第一个父类的属性和方法(根据类的魔法属性mro的顺序来查找:类名.__mro__)

          

      3. 多个父类中,不重名的属性和方法,不会有任何影响。

       

    五. 重写父类 : 在子类中定义一个和父类同名的方法,就叫作重写父类。

             如果子类中有和父类同名的方法,将来执行时,子类会优先调用自己里面的方法.

             继承链:     当前类à 直接父类à…….._--> object所有类的基类

          ## 调用被重写的父类方法

               子类重写了父类的方法, 仍然想执行父类中的方法,则可以在类中使用super()来调用方法.

      def 方法名:

            方法一 : 父类.方法名(self)

            方法二:  super (子类,self).方法名 ( )    括号里面找的是当前类的父类

            方法三:   super().方法名 ( )     直接调用super函数,会直接找当前的父类,即继承中的下一个类/父类

# 类的继承
class A(object):
    def action(self):
        print('我是 A 的方法')


class B(A):
    def action(self):
        print("我是 B 的方法")

    def demo(self):
        #  子类重写了父类的方法,还想调用父类的方法
        # A.action(self)                    # 方式一
        # super(B, self).action()           # 方式二
        super().action()


C = B()
C.action()   # 我是 B 的方法
C.demo()     # 我是 A 的方法

    六.   私有权限

           面向对象的 三大特征:封装 , 继承 , 多态

  封装的意义:

  1. 将属性和方法放到一起做为一个整体,然后通过实例化对象来处理;
  2. 隐藏内部实现细节,只需要和对象及其属性和方法交互就可以了;
  3. 对类的属性和方法增加 访问权限控制。

私有权限:在属性名和方法名 前面 加上两个下划线 __

  1. 类的私有属性 和 私有方法,都不能通过对象直接访问,但是可以在本类内部访问;
  2. 类的私有属性 和 私有方法,都不会被子类继承,子类也无法访问;
  3. 私有属性 和 私有方法 往往用来处理类的内部事情,不通过对象处理,起到安全作用。

多态(鸭子类型):  继承或调用不同的类,会有不同的状态.既可以调用父类,也可以调用子类.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值