• 018.Python之面向对象与内置函数补充


    一、面向对象编程

    (一)什么是面向对象编程

    面向对象编程是一种编程套路,我们可以来跟面向过程编程做个对比。

    1.面向过程编程

    面向过程编程的核心是过程,过程指的是做事的步骤,即做事的先后顺序,基于该思想编写的程序,就相当于一条条流水线。

    (1)优点

    复杂的问题流程化,进而变得简单化。

    (2)缺点

    扩展性差。

    2.面向对象编程

    面向对象编程的核心是对象,对象就是一个用来盛放/整合相关数据与相关功能的容器。

    (1)优点

    程序解耦合强,扩展性好。

    (2)缺点

    比面向过程复杂,不适合扩展性低的使用场景,容易出现过度设计的问题。

    (二)类与对象的使用

    1.类与对象是什么

    类即类别/种类,是面向对象设计最重要的概念,对象是数据与功能的集合体,而类则是对象之间相同数据与功能的集合体。

    对象1:
        # 学生1的数据
        name = "egon"
        age = 18
        gender = "male"
    
    对象2:
        # 学生2的数据
        name = "王三炮"
        age = 19
        gender = "female"
    
    对象3:
        # 学生3的数据
        name = "李大炮"
        age = 20
        gender = "male"
        
    学生类:
        # 学生对象相同的数据
        school = "上海校区"
        # 学生对象相同的功能
        选课功能
    

    2.类的定义与使用

    (1)在程序中必须先定义(类)

    定义类就是申请内存空间,把对象之间共同的数据与功能存起来。

    类在定义的时候就会立即执行类体代码,会产生类的名称空间,然后类名指向该名称空间。

    class Student:
        school = "上海校区"
    
        def choose_course(self):
            print("正在选课")
    	# 代码定义后会立即执行
        print("====>")       # ====>
    # 
    print(Student.__dict__)  # {'__module__': '__main__', 'school': '上海校区', 'choose_course': <function Student.choose_course at 0x0000016AE4258040>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
    
    需要注意的点:
    1)类中可以有任意python代码,这些代码在类定义阶段便会执行;
    2)因而会产生新的名称空间,用来存放类的变量名与函数名,可以通过Student.__dict__查看
    3)点是访问属性的语法,类中定义的名字,都是类的属性
    

    (2)后使用(产生对象)

    调用类来产生对象,调用类的过程又称之为实例化。

    调用类的本质:产生一个与类相关联的子空间。

    # 定义完类之后,接下来就是调用类来产生对象
    stu1 = Student()  # 实际上相当于创建了一个空对象 <__main__.Student object at 0x00000228F1CE5B50>    print(stu1.__dict__) {}
    stu2 = Student()
    stu3 = Student()
    
    stu1.__dict__["name"] = "egon"  # 对象调用.__dict__功能,用来保存对象属性变量的键值对
    # stu1.name = "egon"  # 简化下来可以这样写,本质上实现的功能是一样的
    stu1.__dict__["age"] = 18
    # stu1.age = 18  
    stu1.__dict__["gender"] = "male"
    # stu1.gender = "male"
    
    print(stu1.__dict__)  # {'name': 'egon', 'age': 18, 'gender': 'male'}
    

    (三)详解.__ init __方法以及属性操作

    1.使用.__ init __方法

    python为类内置了一系列特殊属性:

    # 常用的内置属性
    类名.__name__# 类的名字(字符串)
    类名.__doc__# 类的文档字符串
    类名.__base__# 类的第一个父类(在讲继承时会讲)
    类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)
    类名.__dict__# 类的字典属性
    类名.__module__# 类定义所在的模块
    类名.__class__# 实例对应的类(仅新式类中)
    
    类的其他特殊属性
    

    在调用类的过程中,我们需要给对象定制各自独有的属性,在类实例化之后再增加属性过于繁琐,所以python提供了在类内部增加__ init __ 方法,可以在实例化(调用类)的过程中就为对象初始化、传值。

    class Student:
        school = "上海校区"
        #           空对象,"egon",18,"male"
        def __init__(self, x, y, z):
            self.name = x  # 空对象.name="egon"
            self.age = y  # 空对象.age=18
            self.gender = z  # 空对象.gender="male"
            # print("===>")
            # 该函数内可以有任意代码,但是该函数不能返回非None值
            # return 123
    
        #                 stu1
        def choose_course(self):
            print('%s 正在选课' %self.name)
    
        def func(self,x,y):
            print(self.name,x,y)
    
    stu1 = Student("egon",18,"male")
    stu2 = Student("王三炮",19,"female")
    stu3 = Student("李大炮",20,"male")
    # 调用类的过程:
    # 1、会先创造一个与类相关联的子空间,也就对象=》空对象
    # 2、自动触发类内__init__(空对象,"egon",18,"male")
    # 3、返回一个初始化好的对象,我们可以赋值给一个变量名
    

    2.类属性操作

    类与对象都可以通过 . 来访问属性来完成增删改查的操作

    (1)访问类的数据属性

    Student.school = "Shanghai"  # 修改类的属性
    
    Student.xxx = 111  # 增加类的属性
    
    del Student.xxx  # 删除类的属性
    

    (2)访问类的函数属性

    类的函数它就是一个普通函数,该传几个参数就传几个参数。

    print(Student.choose_course)  # <function Student.choose_course at 0x00000228E5628280>
    Student.choose_course(stu1)  # egon 正在选课  传入参数后立即执行
    

    3.对象属性操作

    (1)属性查找顺序:

    对象_._属性,会先从对象自己的空间里找,没有的话去类里面找。

    (2)类中的定义的数据属性为了给对象用的,而且是所有对象共享,大家访问的都是同一个地址。

    print(id(Student.school))  # 1702345007920
    print(id(stu1.school))  # 1702345007920
    print(id(stu2.school))  # 1702345007920
    print(id(stu3.school))  # 1702345007920
    
    Student.school = "!!!"  # 修改类的数据属性,所有对象都会跟着修改
    print(stu1.school)  # !!!
    print(stu2.school)  # !!!
    
    stu1.school = "YYY"  # 修改对象的数据属性,其他对象以及类都不会发生变化
    print(stu1.__dict__)  # {'name': 'egon', 'age': 18, 'gender': 'male', 'school': 'YYY'}
    print(stu1.school)  # YYY
    print(Student.school)  # !!!
    print(stu2.school)  # !!!
    print(stu3.school)  # !!!
    

    (3)类中的定义的函数属性,类可以调用,但就是一个普通函数,而类中函数通常都是为对象准备的,也就是说是给对象用的,如何给对象用?绑定给对象。

    # 绑定的方法
    print(Student.choose_course)  # <function Student.choose_course at 0x0000023962238280>
    print(stu1.choose_course)  # <bound method Student.choose_course of <__main__.Student object at 0x0000023962225B50>>
    
    stu1.choose_course() # choose_course(stu1)  egon 正在选课
    stu2.choose_course() # choose_course(stu2)  王三炮 正在选课
    stu3.choose_course() # choose_course(stu3)  李大炮 正在选课
    
    stu1.func(18,"male")  # egon 18 male
    

    二、常用内置函数补充

    (一)eval()

    用来执行一个字符串表达式,并返回表达式的值

    >>> n=81
    >>> eval("n + 4")
    85
    
    dic={"k1":111}
    with open('a.txt',mode='wt',encoding='utf-8') as f:
        f.write(str(dic))
    
    with open('a.txt',mode='rt',encoding='utf-8') as f:
        line=f.read() # line="{'k1': 111}"
        # print(type(line))  # <class 'str'>
        line=eval(line)  
        print(line['k1'])  # 111
    

    (二)forzenset()

    s=frozenset({1,2,3})
    print(s)  # frozenset({1, 2, 3})
    

    (三)pow()

    函数是计算x的y次方,如果z在存在,则再对结果进行取模,其结果等效于pow(x,y) %z

    print(pow(10, 3))  # 1000 # 10 ** 3
    print(pow(10, 3, 3))  # 1  # 10 ** 3 % 3
    

    (四)reversed()

    reversed 函数返回一个反转的迭代器。

    l=[111,'aaa',333]
    res=reversed(l)
    print(res)  # <list_reverseiterator object at 0x0000020AFE87F0D0>
    for x in res:
        print(x)  # 333
                  # aaa
                  # 111
    l=list(reversed(l))
    print(l)  # [333, 'aaa', 111]
    

    (五)round()

    round() 将一个数字四舍五入到给定的十进制精度中,默认精度是小数点后0位。

    print(round(4.6))  # 5 
    print(round(4.5))  # 4
    

    (六)slice()

    切片函数操作

    l=[111,222,333,44,555,666,777,888]
    
    s=slice(0,5,2)
    
    print(l[0:5:2]) # 0 2 4 [111, 333, 555]
    print(l[s]) # 0 2 4 [111, 333, 555]
    
    msg="hello world"
    print(msg[s])  # hlo
    

    (七)sorted()

    返回一个新的列表,其中包含来自可迭代对象的所有元素,并默认按升序排列。

    # 语法:
    sorted(iterable, cmp=None, key=None, reverse=False)
    
    # 参数:
    1)iterable -- 可迭代对象。
    2)cmp -- 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。
    3)key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
    4)reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。
    
    l = [444, 111, 222, 555, 666, 333, 777, 888]
    new_l = sorted(l)
    print(new_l)  # [111, 222, 333, 444, 555, 666, 777, 888]
    
    dic={
        'zegon':3000,
        "lxx":2000,
        'axx':4000
    }
    res=sorted(dic,key=lambda x:dic[x],reverse=True)
    print(res)  # ['axx', 'zegon', 'lxx']
    

    (八)sum()

    求和函数,第二个元素用于相加

    # 语法:
    sum(iterable[, start])
    
    # 参数:
    1)iterable -- 可迭代对象,如:列表、元组、集合。
    2)start -- 指定相加的参数,如果没有设置这个值,默认为0。
    
    >>>sum([0,1,2])  
    3  
    >>> sum((2, 3, 4), 1)        # 元组计算总和后再加 1
    10
    >>> sum([0,1,2,3,4], 2)      # 列表计算总和后再加 2
    12
    

    (九)zip()

    函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象(python2中直接返回列表),这样做的好处是节约了不少的内存。我们可以使用 list() 转换来输出列表。

    msg = {"name": "egon"}
    l = [111, 222, 333]
    res = zip(msg, l)
    print(list(res))  # [('name', 111)]
    
    msg = "hello"
    l = [111, 222, 333]
    res = zip(msg, l)
    print(res)  # <zip object at 0x0000012F071D1680>
    print(list(res))  # [('h', 111), ('e', 222), ('l', 333)]
    
  • 相关阅读:
    thinkphp tp5 常用 functions
    nginx配置虚拟机 vhost 端口号 域名 区分虚拟机
    thinkphp tp5 模板 引擎 字符串 截取 函数 省略 显示
    C++运算符重载
    c++纯虚函数
    c++面向对象模型---c++如何管理类,对象以及它们之间的联系
    c++多态
    c++友元函数
    c语言的函数指针
    c++两种字符串赋值方式 并介绍 C语言下遍历目录文件的方式
  • 原文地址:https://www.cnblogs.com/huluhuluwa/p/13194016.html
Copyright © 2020-2023  润新知