zoukankan      html  css  js  c++  java
  • 面向对象

    本篇文章的主要内容为内置函数、匿名函数、递归函数、面向对象基础知识、面向对象的组合、面向对象的继承以及面向对象的多态。

    1.内置函数

    '''
    整体说明:
    01 研究python的内置函数。
    02 以下内置函数都是常用的,并且比较重要的。
    '''
    
    # 01 locals:当前作用域的所有的变量  **
    # 0101 当作用域为全局变量,输出全局的变量。
    name = '太白'
    age = 25
    
    
    def func1():
        a1 = 'Ws'
        b1 = {'name': '马玉刚'}
    
    
    func1()
    print(locals())   # 打印出所有的全局变量,以字典的形式输出,其中name = '太白'
    
    # 0102 当前作用域为局部变量,输出局部的变量。
    name = '太白'
    age = 25
    
    
    def func1():
        a1 = 'Ws'
        b1 = {'name': '马玉刚'}
        print(locals())  # 打印函数func1的局部变量,以字典的形式输出,其中name = '马玉刚'
    
    func1()
    
    # 02 globals: 永远获取的是全局作用所有的变量等。  **
    
    name = '太白'
    age = 25
    
    
    def func1():
        a1 = 'Ws'
        b1 = {'name': '二狗'}
        print(globals())   # 打印出所有的全局变量,以字典的形式输出,其中name = '太白'
    
    
    func1()
    print(globals())   # 打印出所有的全局变量,以字典的形式输出,其中name = '太白'
    
    # 03 eval:执行字符串类型的代码,并返回最终结果。(慎用:由于采用用户输入或者接口对接的时候如果不校验直接执行的话, 则比较容易被黑客作为攻击的入口)
    eval('2 + 2')  # 4
    
    n = 81
    eval("n + 4")  # 85
    
    eval('print(666)')  # 666
    
    # 04  exec:执行字符串类型的代码 (慎用:原因同上)
    s = '''
    for i in [1,2,3]:
        print(i)
    '''
    exec(s)
    
    #04 print  输出
    ''' 源码分析
    def print(self, *args, sep=' ', end='
    ', file=None): # known special case of print
        """
        print(value, ..., sep=' ', end='
    ', file=sys.stdout, flush=False)
        file:  默认是输出到屏幕,如果设置为文件句柄,输出到文件
        sep:   打印多个值之间的分隔符,默认为空格
        end:   每一次打印的结尾,默认为换行符
        flush: 立即把内容输出到流文件,不作缓存
        """
    '''
    
    print(111, 222, 333, sep='*')  # 111*222*333
    
    print(111, end='')
    print(222)  # 两行的结果 111222
    
    f = open('log', 'w', encoding='utf-8')
    print('写入文件', file = f, flush=True)
    
    # 05 hash:获取一个对象的哈希值(可哈希对象:int,str,Bool,tuple)
    print(hash(12322))
    print(hash('123'))
    print(hash('arg'))
    print(hash('alex'))
    print(hash(True))
    print(hash(False))
    print(hash((1, 2, 3)))
    
    
    '''
    执行结果:
    12322
    -2996001552409009098
    -4637515981888139739
    2311495795356652852
    1
    0
    2528502973977326415
    '''
    
    06 open:函数用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写。
    
    07 __import__ :模块相关,函数用于动态加载类和函数
    
    # 08 help:用于查看函数或模块用途的详细说明。
    print(help(str))
    
    # 09 callable  判断对象是否可调用,如果返回True,object仍然可能调用失败;但如果返回False,调用对象ojbect绝对不会成功。  **
    a1 = 'barry'
    def func1():
        print(666)
    print(callable(a1))   # False
    
    print(callable(func1))  # True
    
    # 10 dir :查看内置属性,函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。
    # 如果参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息。
    
    dir
    print(dir('alex'))
    
    # 11 进制转换(3)(1)bin:将十进制转换为二进制并且返回。(2)oct:将十进制转换为八进制字符串并返回。(3)hex:将十进制转换为十六进制字符串并返回。
    
    
    print(bin(10), type(bin(10)))  # 0b1010 <class 'str'>
    print(oct(10), type(oct(10)))  # 0o12 <class 'str'>
    print(hex(10), type(hex(10)))  # 0xa <class 'str'>
    
    # 12 数学运算共7个:abs,divmod,round,pow,sum,min,max
    # abs:函数返回数字的绝对值。
    # divmod:计算除数与被除数的结果,返回一个包含商和余数的元组(a // b, a % b)。分页会用到,返回商数和余数。**
    print(divmod(7, 3))  # (2,1)
    # round:保留浮点数的小数位数,默认保留整数。
    # pow:求x**y次幂。
    # sum:对可迭代对象进行求和计算(可设置初始值)。
    print(sum([i for i in range(10)]))  # 默认初始值是0,输出结果为45.
    print(sum([i for i in range(10)], 100))  # 设置默认初始值为100,输出结果为145。
    # min:返回可迭代对象的最小值(可加key,key为函数名,通过函数的规则,返回最小值)。 ***
    # 常规式的输出最小值
    print(min(1, 2, 3, 4, 5))
    print(min([1, 2, 3, 4, 5]))
    print(min([('alex', 3), ('太白', 1), ('wS', 2)]))  # 按照unicode编码去比较大小,首先比较每个元素中的第一个,之后逐个比较,直至比较出大小来即可。
    # 加key的输出最小值(key为函数名)
    # min 默认将可迭代对象中的每个元素依次传入函数中,按照函数的返回值去取最小元素。
    l1 = [('alex', 3), ('太白', 1), ('wS', 2)]
    
    
    def func(x):
        return x[1]  # min将可迭代对象中的每个元素依次传入函数中,并且按照返回值取最小元素。该返回值是将列表中每个元素的第二个作为返回值返回。
    
    
    print(min(l1, key=func))  # ('太白', 1)
    #
    # max:返回可迭代对象的最大值(可加key,key为函数名,通过函数的规则,返回最大值)。 ***
    # max的使用和min一样。
    
    # 13 reversed:将一个序列翻转,返回一个新的翻转的迭代器。 ***
    l1 = [2, 3, 4, 1]
    l2 = reversed(l1)
    print(list(l2))
    
    # 14 format 字符串可以提供的参数,指定对齐方式,<是左对齐, >是右对齐,^是居中对齐。
    print(format('test', '<20'))  # 以20个字符为长度,进行左对齐
    print(format('test', '>20'))
    print(format('test', '^20'))
    
    # 15 bytes:用于不同编码之间的转化。 **
    s1 = '太白'
    # unicode ---> utf-8 bytes
    b1 = s1.encode('utf-8')
    print(b1)
    # utf-8 bytes ---> unicode
    s2 = b1.decode('utf-8')
    print(s2)
    
    s1 = '太白'
    # unicode ---> utf-8 bytes
    b1 = bytes(s1, encoding='utf-8')
    print(b1)
    
    # 16 ord:输入字符找该字符编码的位置
    print(ord(''))  # 20013
    print(ord('a'))   # 97,
    
    # 17 chr:输入位置数字找出其对应的字符
    print(chr(97))   # a
    print(chr(20013))  #
    
    #18 ascii:是ascii码中的返回该值,不是就返回/u...
    print(ascii('a'))   # 'a'
    print(ascii(''))  # 'u4e2d'
    
    # 19 repr:返回一个对象的string形式(原形毕露)。
    s1 = "alex"
    l3 = '[1,2,3]'
    print(s1)  # alex
    print(l3)  # [1,2,3]
    print(repr(s1))  # 'alex'
    print(repr(l3))  # '[1,2,3]'
    
    # 20 %r-也会使字符串原型毕露,用处是引用别人说的话时,如果需要保留单引号的时候,就需要用%r。
    s1 = '我叫%s, 我是%r' % ('alex', 'sb')
    print(s1)
    
    # 21 sorted:对所有可迭代的对象进行排序操作。
    l1 = [1, 2, 7, 6, 5, 4]
    l2 = sorted(l1)
    print(l2)  # [1, 2, 4, 5, 6, 7]
    
    l1 = [('alex', 3), ('太白', 1), ('wS', 2), ('wS', 4)]
    
    
    def func(x):
        return x[1]
    
    
    new_l = sorted(l1, key=func, reverse=True)  # sorted:将可迭代对象中的每个元素依次传入函数中,并且将每个元素中的第二个返回进行排序,同时进行倒序输出。
    print(new_l)  # [('wS', 4), ('alex', 3), ('wS', 2), ('太白', 1)]
    
    # 22 # enumerate::枚举,返回一个枚举对象。  ***
    l1 = ['太白%s' % i for i in range(10)]
    
    for index, i in enumerate(l1, 10):  # 设置默认索引数字从10开始,i从0开始进行循环
        print(index, i)
    
    # 23 all:可迭代对象中,全都是True才是True **
    print(all([1, 2, True, 100]))  # True
    
    # 24 any:可迭代对象中,有一个True 就是True **
    print(any(['', 0]))  # False
    
    '''
    # 24  zip 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
    如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同。   ***
    '''
    l1 = [1, 2, 3, 6, 7, 8, 9]
    l2 = ['a', 'b', 'c', 5]
    l3 = ('*', '**', (1, 2, 3))
    
    print(zip(l1, l2, l3))  # 生成一个可迭代对象
    for i in zip(l1, l2, l3):
        print(i)
    
    '''
    <zip object at 0x0000000001E95608>
    (1, 'a', '*')
    (2, 'b', '**')
    (3, 'c', (1, 2, 3))
    '''
    
    # 25  filter 返回是迭代器  类比成列表推导式:筛选模式  ***
    l1 = [i for i in range(100) if i % 2 == 0]
    print(l1)
    
    
    l2 = [1, 2, 3, 4, 5, 6]
    
    
    def func(x):
        return x % 2 == 0  # 筛选条件
    
    
    obj1 = filter(func, l2)
    print(list(obj1))  # [2, 4, 6],切记一定要加上list,否则只是一个迭代器。
    
    # 26 map: 返回一个迭代器  类比成列表推导式:循环模式  ***
    l1 = [1, 2, 3, 4, 5, 6]
    
    
    def func(x):
        return x ** 2  # 返回值
    
    
    print(list(map(func, l1)))

    2.匿名函数

    '''
    整体说明;
    01 一句话函数,一行代码实现的函数
    02 格式:函数名 = lambda 输入:返回值
    '''
    
    # 01 计算两个数字的和
    func1 = lambda x, y: x + y
    print(func1(2, 3))
    
    # 02 三个数的运算
    
    func2 = lambda x, y, z: (x + y - z) * 2
    print(func2(2, 5, 6))
    
    # 03 匿名函数与内置函数结合使用
    l1 = [1, 2, 3, 4, 5, 6]
    obj1 = filter(lambda x: x % 2 == 0, l1)
    print(obj1)  # <filter object at 0x00000000021AE2E8>,直接打印是一个迭代器
    print(list(obj1))  # 打印一个列表[2, 4, 6]
    
    # 04 输出字典种value最大的key
    l = [3, 2, 100, 999, 213, 1111, 31121, 333]
    dic = {'k1': 10, 'k2': 100, 'k3': 30}
    
    ret = max(dic, key=lambda x: dic[x])
    print(ret)

    3.递归函数

    '''
    整体说明:
    01 自己用自己。
    02 默认的递归次数:999(998)
    03 递归函数一定要有返回值(返回值基本上都是函数自己调用自己)
    
    '''
    
    # 01 用递归函数实现斐波那契数列
    # 1 1 2 3 5 8 13 21 .....
    # 1 2 3 4 5 6 7  8 .....
    
    
    
    def fib(n):
        if (n == 1 or n == 2):
            return 1
        else:
            return fib(n - 1) + fib(n - 2)
    
    
    print(fib(20))
    
    '''
    推到过程:
    fib(3) = fib(2) + fib(1)
    fib(4) = fib(3) + fib(2)
    。。。。
    fib(n) = fib(n - 1) + fib(n - 2)
    '''

    4.面向对象基础知识

    '''
    整体说明:
    01 相同功能的函数进行分类。
    02 面向对象的特点:
        (1)它是将某些相关的功能(函数)封装到一起。
        (2) 站在上帝的角度,创建一个公共模板,然后通过模板创造不同的对象。
    03 类:具有相同属性和技能的一类事物。
    04 对象:类的具体表现。
    05 类的分析方法:
        (1)结构分析:类一般分为两个部分,即静态变量(静态属性/静态字段),动态方法(函数)。
        (2)思想分析:创建一个类的公共模板,通过创建个体对象可以享有公共方法。
    06 类的调用:类中的静态属性一般通过类名去调用或者改变;类中的动态方法一般通过对象去执行。
    07 类名的应用
        (1)类名调用类中的静态属性。
            a)方法一:__dict__  只能查询(不能增删改) 类中所有的静态属性,动态方法。
            b)方法二: 万能的点 .  可以查,可以改,可增,可删。
        (2)类名执行类中的动态方法。(一般不建议用类名执行,除非是特殊方法:类方法,静态方法)
    08 实例化对象:类名+()就是一个实例化对象的过程,具体步骤如下:
        (1)实例化对象在内存中产生一个对象空间(内存地址)。
        (2)自动执行 __init__方法并且将对象空间传给了self参数。***
        (3)在 __init__方法中,给对象空间封装一些静态属性。
    09 对象的应用
        (1)对象调用类的静态属性
        (2)万能的点: .可以调用类中的静态属性。
        (3)对象执行类中动态方法:
    10  self 约定俗成 self,类中的方法的第一个参数要设定为self,在对象调用方法时,会自动将对象空间传给self。
    11 __init__方法:作用是给对象封装属性。
    '''
    
    # 01 定义一个类person
    class Person:
        mind = '有思想'
        animal = '高级动物'
        language = '文字语言'  # 静态属性,静态变量 静态字段
    
        def work(self):  # 函数 方法,动态方法,动态属性。
            print('人类都会工作')
    
        def eat(self):
            print('人类都需要吃饭')
    
    # 02 类名的应用
    # 0201 类名调用类中静态属性
    
    class Person:
        mind = '有思想'
        animal = '高级动物'
        language = '文字语言'  # 静态属性,静态变量 静态字段
    
        def work(self):  # 函数 方法,动态方法,动态属性。
            print('人类都会工作')
    
        def eat(self):
            print('人类都需要吃饭')
    # 方法一:__dict__  只能查询(不能增删改) 类中所有的静态属性,动态方法。
    print(Person.__dict__)
    print(Person.__dict__['mind'])
    Person.__dict__['mind'] = '无思想的' # 不能这样修改,因为方法一只能查询,不能增删改
    print(Person.__dict__)
    
    # 方法二: 万能的点 .  可以查,可以改,可增,可删。
    print(Person.animal)
    Person.animal = '低级动物'  # 修改类中的静态属性
    Person.name = '有姓名'  # 增加类中的静态属性
    print(Person.animal)
    del Person.animal
    # print(Person.animal)   # 报错,因为上一步已经删除类Person中animal静态属性,所以会报错。
    print(Person.__dict__)
    
    # 0202 类名执行类中的动态方法 (一般不建议用类名执行,除非是特殊方法:类方法,静态方法)
    Person.work('alex')   #  不建议用类名执行动态方法。
    
    # 03 __init__:作用是给对象封装属性。
    # 以下是定义游戏角色的类Game_Role
    class Game_Role:
        a1 = '英雄联盟'
        name = '太白'
        def __init__(self, name, sex, ad, hp):  # __init__方法,特殊方法: 给对象封装属性
            # print(self)
            # print(666)
            ''' 以下给对象封装的属性'''
            self.name = name
            self.sex = sex
            self.ad = ad
            self.hp = hp
    
    
        def fight(self,*args, **kwargs):
            pass
    
    gailun = Game_Role('盖伦', 'man', 30, 500)  # 进行对象的实例化,即gailun = Game_Role,默认执行__init__函数,给对象封装属性。
    print(gailun.name)  # 通过万能的点,由实例化的对象进行静态属性的展示。
    
    # 04 对象的应用。
    # 0401 对象调用类中的静态属性;通过万能的点:.可以调用类中的静态属性。
    print(gailun.name)  # 通过万能的点,由实例化的对象进行静态属性的展示。
    # 0402 对象执行类中的动态方法。
    class Game_Role:
        a1 = '英雄联盟'
        name = '太白'
        def __init__(self, name, sex, ad, hp):  # __init__方法,特殊方法: 给对象封装属性
            # print(self)
            # print(666)
            ''' 以下给对象封装的属性'''
            self.name = name
            self.sex = sex
            self.ad = ad
            self.hp = hp
    
    
        def fight(self,*args, **kwargs):
            pass
    
        def work(self):
            self.hobby = '大刀' # 增加对象的属性
            print(self.__dict__)
    
    
    gailun = Game_Role('盖伦', 'man', 30, 500)  # 进行对象的实例化,即gailun = Game_Role,默认执行__init__函数,给对象封装属性。
    gailun.work()
    print(gailun.hobby)  # 大刀
    
    # 0403 对象查看自己的空间属性
    # 查看全部:__dict__
    # 查看某个对象自己的静态属性:万能的点,实现增删改查。
    print(gailun.name)
    print(gailun.sex)
    gailun.name = 'GAIlun'
    gailun.hobby = '大刀'
    print(gailun.hobby)
    print(gailun.__dict__)

    5.面向对象组合

    '''
    整体说明:
    01 对象与对象之间是不能相互访问的, 彼此独立。
    02 对象可以访问类中的所有内容,但是类名不能访问对象中的内容。
    03 组合的作用:让类的对象和另一个类的对象发生关联,从而可以互相访问。(通过一个对象的属性是另一个类的对象来实现)
    '''
    
    '''
    程序说明:
    01 定义了两个类,即角色类和武器类,其中角色类中的ad代表攻击力,hp代表血量。
    02 需求是盖伦使用大宝剑攻击沟通一次(只计算工具本身对狗头血量的消耗,暂时忽略盖伦本身的攻击力)
    '''
    class Game_Role:
        area = '召唤师峡谷'
        
        def __init__(self, name, sex, ad, hp):
            self.name = name
            self.sex = sex
            self.ad = ad  # 攻击力
            self.hp = hp  # 血量
        
        def fight(self, role1):
            role1.hp = role1.hp - self.ad
            print('%s 攻击 %s, %s还剩余%s' % (self.name, role1.name, role1.name, role1.hp))
            # print(self, role1)
        
        def equit_weapon(self, wea): # 组合: 对象中的属性是另一个类的对象,将Weapon类的对象sword作为Game_roles类的实例化对象P1的封装的属性。
            self.wea = wea
    
    
    class Weapon:
        def __init__(self, name, ad):
            self.name = name
            self.ad = ad
        
        def wea_attack(self, role1, role2):
            role2.hp = role2.hp - self.ad
            print('%s 利用 %s 攻击 %s, %s还剩余%s' % (role1.name, self.name, role2.name, role2.name, role2.hp))
    
    
    p1 = Game_Role('盖伦', 'man', 30, 500)
    p2 = Game_Role('狗头', '', 50, 250)
    # p3 = Game_Role('诺克', 'man', 50, 350)
    # p1.fight(p2)
    
    sword = Weapon('大宝剑', 40)
    # print(sword)
    # sword.wea_attack(p1, p2)
    p1.equit_weapon(sword)  # 此方法就是给p1对象封装一个属性,属性值是sword对象
    # print(p1.wea.name)
    # # print(p1.wea)
    p1.wea.wea_attack(p1, p2)  # 通过p1.wea找到sword 然后在sword.wea_attack执行方法,其中self省略了。

    6.面向对象的继承

    '''
    整体说明:
    01 继承的作用:
        (1)节省代码
        (2)提高效率
        (3)让类之间产生关联
    02 继承的分类
        (1)单继承
        (2)多继承
    03 类的分类
        (1)经典类:不继承object的类。
        (2)新式类:默认继承object类
        (3)说明:python2x中经典类和新式类共存;python3x中全部都是新式类
    04 在继承的时候,执行的顺序是先在子类/派生类中寻找收含有变量,如果含有则直接输出,如果不含有,则根据“类对象指针”寻找
       父级中是否含有该变量,如果有则直接输出,如果不含有,则继续寻找父级的父级中是否含有该变量,直至遍历了所有的父级类,仍
       没有则报错。
    05  两种方法解决既要执行子类的方法,又要执行父类的方法
        (1)方法一:直接调用另一个类的方法
        (2)方法二:使用super() 自动将self传给父类的self
    '''
    
    
    # 01 单继承
    '''
    说明:
    01 Animal是父类/基类Person是子类/派生类。
    '''
    
    #  0101 单继承说明
    class Animal:
        a1 = '太白'
    
        def __init__(self, kind, age, sex):
            self.kind = kind
            self.age = age
            self.sex = sex
    
        def func1(self):
            print(666)
    
    
    class Person(Animal):
        a1 = 'alex'  # 由于子类中含有该变量,所以直接输出变量值 alex,不会根据类对象指针去寻找父级类中是否含有该变量。
        pass
    print(Person.a1)
    
    # 0102 单继承说明
    '''
    两种解决方式解决既要执行子类的方法,又要执行父类的方法
    01 第一种  Animal.__init__(self, k1, a1, s1) 直接调用另一个类的方法
    02 第二种:super().__init__(k1,a1,s1)  # 自动将self传给父类的self
    '''
    
    
    class Animal:
        def __init__(self, kind, age, sex):
            self.kind = kind
            self.age = age
            self.sex = sex
    
        def bark(self):
            print('动物都会叫')
    
    
    class Dog(Animal):
        def __init__(self, k1, a1, s1, bite):
            '''
            self = d1
            k1 = '藏獒'
            ....
            '''
            Animal.__init__(self, k1, a1, s1)   # 方法一:Animal.__init__(self, k1, a1, s1) 直接调用另一个类的方法
            # super().__init__(k1, a1, s1)  # 方法二: 自动将self传给父类的self
            self.bite = bite  #  新增Dog的属性,咬合力 bite
    
        def bark(self):
            super().bark()  # 调用父类(超类)中需要执行的动态方法。
            print('汪汪汪')
    
    
    class Cat(Animal):
        def bark(self):
            print('喵喵喵')
    
    
    class chick(Animal):
        def bark(self):
            print('大爷,来玩呀')
    
    d1 = Dog('藏獒', 3, '', 300)  # 类Dog的实例化对象d1。
    d1.bark()  # 对象执行类中的动态方法。
    
    # 02 多继承
    # 新式类:C3算法 mro 主要是查询 新式类的多继承的继承顺顺序
    
    class A:
        def func(self):
            print(666)
        pass
    
    class B:
        def func(self):
            print(666)
        pass
    
    class C(A):
        def func(self):
            print(666)
        pass
    
    class D(B):
        def func(self):
            print(666)
        pass
    
    class E(C,D):
        # def func(self):
        #     print(666)
        pass
    
    e1 = E()
    # e1.func()
    
    print(E.mro())

    7.面向对象的多态

    '''
    整体说明:
    01 Pyhon不支持Java和C#这一类强类型语言中多态的写法,但是原生多态。
    02 Java或C#中定义函数参数时,必须指定参数的类型,而python不需要强制制定数据类型。
    '''
  • 相关阅读:
    Lync二次开发
    Socket 一对多通信
    DBImport V3.1 数据互导工具及文档生成器更新发布
    Sql学习第六天——SQL 巩固练习(用到了前几天几个知识点)
    文件监控
    Google Protocol Buffers 入门
    [原]常用Linux命令总结[Thx for commandlinefu]
    清理SQL Server日志释放文件空间
    ASP.NET MVC动态二级域名及ASP.NET管道机制
    搜索引擎——JobSearch简介
  • 原文地址:https://www.cnblogs.com/mayugang/p/9945809.html
Copyright © 2011-2022 走看看