day06_雷神_面向对象初识

day_06

递归函数

自己用自己。一般递归100多次,都没有解决的问题,放弃递归。

count = 0
def func1():
    global count
    count += 1
    print(count)
    func1()

func1()
默认递归深度:998

设置递归深度

import sys
sys.setrecursionlimit(20000)
count = 0
def func1():
    global count
    count += 1
    print(count)
    func1()
func1()

用递归解决一个年龄问题:

""
alex 他比佩奇 大两岁。  4   age(3) + 2
佩奇 他比日天 大两岁。  3   age(2) + 2
日天 他比太白 大两岁。  2   age(1)  + 2
太白:我今年23.         1   23
"""

def age(n):
    if n == 1:
        return 23
    else:
        return age(n-1) + 2
print(age(3))

注意: 必须有return

二分查找

有序的不重复数字列表

l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]

print(l.index(3))  # 查询到66 索引

以前查找索引的方法:

for i in range(len(l)):
    if l[i] == 66:
        print(i)

通过递归的方法:

l1 = [2,3,5,10,15,16]

def two_search(l,aim,start=0,end=None):
    end = len(l) - 1 if end is None else end
    if end >= start:
        mid_index = (end - start) // 2 + start
        if aim > l[mid_index]:
            return two_search(l,aim,start=mid_index+1,end=end)
        elif aim < l[mid_index]:
            return two_search(l,aim,start=start,end=mid_index-1)
        elif aim == l[mid_index]:
            return mid_index
        else:
            return '没有此值'
    else:
        return '没有此值'
print(two_search(l1,5))

错误的例子:因为每次切片,改变了原列表,进而改变了索引。

l = [2,3,5,10,15,16]

def two_search(l,aim):
    mid_index = len(l) // 2
    if aim > l[mid_index]:
        return two_search(l[mid_index+1:],aim)
    elif aim < l[mid_index]:
        return two_search(l[:mid_index],aim)
    elif aim == l[mid_index]:
        return mid_index
    else:
        return '没有此值'

print(two_search(l,16))

面向对象初识

实际工作中,python 都是面向对象,写代码,或者 面向对象+函数写代码。

面向对象编程:上帝式思维。造物者思维。 什么是类?

类:是具有相同属性和技能的一类事物。
对象:实例化的一个类,是类的具体体现。
猫就是类,我家楼下那只小花,这是一个对象。

基本概念:

class Person:  # class 关键字,定义了一个类
    '''
    类里面的所有内容
    '''
    animal = '高级动物' # 静态变量
    soup = '有思想'  # 静态变量

    def __init__(self,name,sex,eye,high,weight,):  # 构造方法

        self.eye = eye  # 属性
        self.name = name
        self.sex = sex
        self.high = high
        self.weight = weight
        print(666)

    def work(self): # 动态变量,动态方法,方法
        print(self)
        # self.job = 'IT'
        print('人会工作....')

以类的角度去调用变量:静态、动态

类操作静态变量有两种方式:一般你想查询全部的静态变量时,用__dict__ 其他全部都用类名.变量名。

1. 类名.__dict__  只能查看,不能增删改
print(Person.__dict__)  # 所有的变量,显示一个字典数据
{'__module__': '__main__', '__doc__': '\n    类里面的所有内容\n    ', 'animal': '高级动物', 'soup': '有思想', '__init__': <function Person.__init__ at 0x000002495E988950>, 'work': <function Person.work at 0x000002495E9889D8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>}

print(Person.__dict__['animal'])

2. 类名.变量名  可增删改
print(Person.animal)
Person.kind = '有性格'
Person.animal = '低等动物'
del Person.kind
print(Person.__dict__)

类操作方法有两种方式:

1,类名.__dict__[方法名]()
print(Person.__dict__['work'](11))  有一个self形参,随便传个实参测试。

2,类名.方法名()
Person.work(11)

如果类操作方法:类名.方法名();

只要创建一个类,里面的内容就已经加载到内存。

对象:类名() 就是实例化一个对象

p1 = Person() # p1 对象,实例化对象,类名()过程就叫做实例化。

p1 = Person() # p1 对象,实例化对象,类名()过程就叫做实例化。

内部进行三步:

1,实例化一个对象,在内存中产生一个对象空间。
2,自动执行init方法,并将这个空间对象。 <__main__.Person object at 0x0000000001F5ABE0> 传给self
3,通过构造方法里的代码给空间对象添加一些属性,并返回给对象。

对象操作属性变量有两种方式:

1,对象.__dict__方法  只能查看,不能增删改。
print(p1.__dict__)

2, 对象.变量名  可增删改查
print(p1.name)
print(p1.eye)
p1.color = '黄皮肤'
print(p1.color)
print(p1, type(p1))  p1是一个对象的内存地址。
print(p1.__dict__)

3, 可以访问类的静态变量
print(p1.animal)
print(p1.soup)

对象操作方法有两种方式:

1, 对象.方法名()
p1 = Person('峰哥','男','大眼睛',176,170)
输出:666
p1.work()
输出:
666
<__main__.Person object at 0x000001D8DF0E7B38>  代表self,p1对象的内存地址。
人会工作....

2. 2,类名.方法名(对象)
Person.work(111)
Person.work(p1)  手动将p1传给self。

类空间,对象空间

通过实例化对象查找属性,先从对象空间找,没有则通过类对象指针从类空间找。

组合

组合:给一个类对象的属性 封装 另一个类的对象。

class Game_person:
    def __init__(self,nickname,sex,hp,ad):
        self.nickname = nickname
        self.sex = sex
        self.hp = hp
        self.ad = ad
    def attack(self,p):
        p.hp -= self.ad
        print('%s攻击了%s,%s还剩%s血量'%(self.nickname,p.nickname,p.nickname,p.hp))

    def weapon_attack(self,wea):
        self.lalala = wea #斧子对象

class Weapon:
    def __init__(self,name,ad):
        self.name=name
        self.ad=ad

    def fight(self,p1,p2):
        p2.hp -= self.ad
        print('%s使用%s打了%s%s血,%s还剩%s滴血'\
              %(p1.nickname,self.name,p2.nickname,self.ad,p2.nickname,p2.hp))

ts = Game_person('泰森','男',200,50)
barry = Game_person('太白','男',100,10)
fuzi = Weapon('斧子',60)

barry.weapon_attack(fuzi)  先把对象fuzi传进去,即完成另一个类对象的封装。
barry.wea.fight(barry,ts)  barry.wea 相当于对象fuzi

继承

继承:可以有效的节省代码。

Animal 父类,基类。
Cat 子类,派生类,

python3x 中,所有的类都默认继承object类,继承object类的类称为新式类。python3 没有经典类。

新式类 :遵循的广度优先。
经典类 :遵循的深度优先。

继承:单继承,多继承。 ??

继承的问题:

class Animal:
    soup = '灵魂'
    def __init__(self,varieties, sex, color):
        self.varieties = varieties
        self.sex = sex
        self.color = color
        print(666)

    def eat(self):
        print('吃')

class Cat(Animal):
    a = Animal.eat
    def eat(self):
        print('猫吃饭')

class Bird(Animal):

    def __init__(self,varieties, sex, color,fly):
        # Animal.__init__(self,varieties, sex, color,)  # 执行父类的方法第一种方式
        # super(Animal,self).__init__(varieties, sex, color,)  # 执行父类的方法第二种方式
        super().__init__(varieties, sex, color,)  # 执行父类的方法第二种方式 省略写法
        self.fly = fly  # 个性化的封装
    def eat(self):
        super().eat()
        print('鸟该吃饭了....')

cat1 = Cat('波斯猫', '公', '橘黄')
cat1.eat()
问题一:
执行顺序,所以执行 猫吃饭.

问题二:
猫,鸟,都有自己独立属性,如何使用共同的属性并且使用独立的属性。
b1 = Bird('鹦鹉','公', '绿色',800)
print(b1.__dict__)
b1.eat()

新式类 :遵循的广度优先。

单继承,如果自己没有,就一直往上找,直到找到为止。

class A:
    def func(self):
        print('A')

class B(A):
    pass
    # def func(self):
    #     print('B')

class C(B):
    # pass
    def func(self):
        print('C')

c1 = C()
c1.func()

多继承,钻石继承,遵循广度优先,(找完B,找C,不会找完B 去找A,那样是深度优先)

class A:
    def func(self):
        print('A')

class B(A):
    pass
    # def func(self):
    #     print('B')

class C(B):
    # pass
    def func(self):
        print('C')

c1 = C()
c1.func()

多继承 钻石继承

class A:
    def func(self):
        print('A')

class B(A):
    pass
    # def func(self):
    #     print('B')

class C(A):
    pass
    # def func(self):
    #     print('C')

class D(B,C):
    pass

d1 = D()
d1.func()

示例2:mro()

class A:
    def func(self):
        print('A')

class B(A):
    pass
    # def func(self):
    #     print('B')

class C(A):
    pass
    def func(self):
        print('C')

class D(B):
    pass
    # def func(self):
    #     print('D')
class E(C):
    pass
    def func(self):
        print('E')
class F(D,E):
    pass
    # def func(self):
    #     print('F')
print(F.mro())

经典类: 深度优先

class A:
    def func(self):
        print('A')

class B(A):
    pass
    # def func(self):
    #     print('B')

class C(A):
    pass
    def func(self):
        print('C')

class D(B,C):
    pass
print(D.mro())
d1 = D()
d1.func()

B没有,会直接去A,不会去C

面试题1

class A:
    def func(self):
        print('A')
    def __init__(self):
        self.func()

class B(A):
    def func(self):
        print('B')
b1 = B()

此时的self就是b1的内存地址,所以结果是执行 print('B'),输出B

猜你喜欢

转载自www.cnblogs.com/houbinglei/p/9268837.html