python 10天快速教程 Day7

2020-07-16  本文已影响0人  XaviSong

本节重点

  1. 面向对象介绍
  2. 简单类与对象
  3. 魔法方法
  4. 继承、super
  5. 私有属性与私有方法

一、面向对象介绍

二、简单类与对象

1、类与对象的关系
2、类的创建

使用class关键字,创建属性与方法。使用新式类的创建形式:class + 类名 + (继承自的父类)。

self,类中的方法中参数,指调用这个方法的对象,说明这个方法要有对象来调用,不能直接使用。

示例:
class Player(object): # 新式类的创建方式
    # 属性
    country = "France"
    # 方法
    def show(self):
        print("我来自法国")
1、通过类创建对象:
player1 = Player()
print(player1) # 内存中开辟了一块空间,空间中存的是对象的内存地址
'''
<__main__.Player object at 0x000002BF92338390>
'''
2、通过对象查看属性:
print(player1.country)
'''
France
'''
3、通过对象调用类方法:
player1.show()
'''
我来自法国
'''
4、查看继承自哪个父类:
print(Player.__base__)
'''
<class 'object'>
'''
5、动态为类添加属性:
Player.wage = 100000
Player.age = 18
print(Player.wage,Player.age)
'''
100000 18
'''

三、类的魔法方法

定义:

类中某些固定名称的方法,在当前需要完成某个功能的操作时,类自行调用,无需对象显式调用。

固定名称:

双下划线开头,双下划綫结尾。如:

__new__,__init__,__str__,__del__等
1、__ new __方法:

当前对象创建的时候就会调用。创建对象时先调用new,然后调用init进行初始化,表示对象创建完成

class Student(object):
    def __new__(cls,*args):
        print("new一个对象")
        print(args) #必须返回父类的new方法(相当于创建对象)
        return object.__new__(cls)
    def __init__(self,name,age):
        super().__init__()
        self.name = name
        self.age = age
        print("初始化完毕")
stu = Student("syp",18)
'''
new一个对象
('syp', 18)
初始化完毕
'''
2、__ init __方法:

根据类创建当前对象时,自动调用这个方法进行初始化,在__ new __之后。

示例:
class Player(object):
    # 属性
    def __init__(self):
        self.country = "France"
        print("自行调用")
    # 方法
    def show(self):
        print("我来自法国")
p1 = Player()
'''
自行调用
(对象一创建,自动调用,会直接打印出上行内容)
'''

print(p1.country) # 实例属性已经初始化
'''
France
'''
3、__ str __ 、__ del __方法

__ str __: 当使用print打印通过该类创建的对象时调用。

__ del __:对象释放自动调用,程序退出或手动删除一个对象时都会调用(原则:引用计数为0时调用)

示例:
import time
class Player(object):
    # init方法中定义实例属性
    def __init__(self,country,name,age):
        self.country = country 
        self.name = name
        self.age = age
        print(self.country,self.name,self.age)
    # str方法定义print该对象时的信息
    def __str__(self):
        return "%s来自于%s联赛,现年%d岁"%(self.name,self.country,self.age)
        
    # del方法
    def __del__(self):
        print("对象释放完毕")

p1 = Player("法国","内马尔",27)
p2 = Player("法国","姆巴佩",19)
time.sleep(3)
print(p1)
'''
法国 内马尔 27
法国 姆巴佩 19
内马尔来自于法国联赛,现年27岁
对象释放完毕
对象释放完毕
'''
4、__ del __结合引用计数理解:

引用计数:内存地址的使用次数

p1 = Player("法国","内马尔",27) # 内存中开辟一块空间,引用计数0->1
p3 = p1 # 引用计数1->2
del p1 # 这里不调用del,因为引用计数还是1
time.sleep(3)
print("程序退出")

'''
法国 内马尔 27
程序退出
对象释放完毕 (退出之后才调用del)
'''

四、继承、super

继承的好处:子类可以复用父类的方法属性。避免冗余代码,基类(父类)中可以放一些重复的代码。反之,父类不可以使用子类的属性与方法。

(1)单继承示例:
class Player(object):
    # init方法中定义实例属性
    def __init__(self,country,name,age):
        self.country = country 
        self.name = name
        self.age = age
    def show(self):
        print(self.country,self.name,self.age)

# 定义明星球员类
class starplayer(Player):
    pass
s1 = starplayer("法国","内马尔",27) # 使用Player父类的属性
s1.show() # 使用player父类方法
(2)多继承示例:

类的继承顺序,影响调用哪个父类方法。通过类名调用mro()方法,找到继承链条,沿链条向上查找方法。

class A(object):
    def show(self):
        print("我是A类")

class B(object):
    def show(self):
        print("我是B类")
        
# 定义一个多继承的类C,继承自A,B
class C(A,B):
    pass

# 类的继承顺序,影响调用哪个父类方法
c = C()
c.show()

# 查看类的继承顺序,沿链向上找,没有就一直向上,最终还没有就报错
print(C.mro())
'''
我是A类
[<class '__main__.C'>, <class '__main__.A'>, <class'__main__.B'>, <class 'object'>]
'''
(3)重写父类方法:

子类继承父类,但是父类方法难以满足子类,可以重写进行覆盖。调用时先从子类找,子类没有就遵循mro原则,向上父类、父类的父类查找(就近原则)。

# 父类
class Father(object):
    def run(self):
        print("在运行")
# 子类
class Son(Father):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def run(self):
        print("%s 在运行"%self.name)
son = Son("syp",19)
son.run()
'''
syp 在运行
'''
(4)super调用父类方法:
示例:
# 父类
class Father(object):
    def run(self):
        print("在运行")
# 子类
class Son(Father):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def run(self):
        # Son表示要去mro链条中获取Son的下一个类
        # self表示你要找的是当前类的继承链
        print(self.__class__.mro())
        super(Son,self).run()
    def soccer(self):
        print("我在踢足球")
son = Son("syp",19)
son.run()
'''
[<class '__main__.Son'>, <class '__main__.Father'>, <class 'object'>]
(Son的下一个是Father,所以去调用Father的run方法)
'''

多继承的情况也是一样的,继承链不分叉,想调用哪个父类的方法,按照super参数按照类型链传就可以了

class A(object):
    def show(self):
        print("我是A类")

class B(object):
    def show(self):
        print("我是B类")
        
# 定义一个多继承的类C,继承自A,B
class C(A,B):
    def show(self):
        super().show() # 默认去本链的父类,等价于super(C,self).show()

c = C()
c.show()
'''
我是A类
'''

# 如果这样写super参数
class C(A,B):
    def show(self):
        super(A,self).show() 
c = C()
c.show()
'''
我是B类
'''
(5)init方法中的super:
示例:
class Father(object):
    def __init__(self,name):
        print("father")
        self.name = name
# 子类
class Son(Father):
    def __init__(self):
        print("son")

s = Son()
print(s.name) # 报错,因为init被重写,并没有继承name属性

super的作用

想继承、就要调用父类的init方法

# 父类
class Father(object):
    def __init__(self,name):
        print("father")
        self.name = name
# 子类
class Son(Father):
    def __init__(self):
        super(Son,self).__init__("syp")

s = Son()
print(s.name) 
'''
father
syp
'''

五、私有属性与私有方法

外部访问不了

示例:
class Person(object):
    def __init__(self,name,age):
        self.name = name # 公有属性
        self.__age = age # 私有实例属性
    def show(self):
        pass
    def __wage(self):
        print("1000000")
p = Person("syp", 19)
print(p.age)
p.__wage()
'''
报错,提示person没有属性age,没有__wage方法
'''

注意:以下代码是添加了同名公有属性,不是访问私有属性

# 动态添加
p.__age = 20
print(p.__age)
查看对象中的属性、方法信息
print(p.__dict__)
'''
{'name': 'syp', '_Person__age': 19, '__age': 20}
私有属性有前缀_Person
'''

print(Person.__dict__)
'''
{'__module__': '__main__', '__init__': <function Person.__init__ at 0x000002335E2A0C80>, 'show': <function Person.show at 0x000002335E2A0488>, '_Person__wage': <function Person.__wage at 0x000002335E2A0F28>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
打印方法所在的内存地址
'''
注意:在python中没有真正的私有方法与私有属性

硬访问:

根据刚才我们看到的前缀,配合前缀使用就可以访问私有的属性和调用私有方法

p._Person__age = 18
print(p.__dict__)
'''
19
'''

p._Person__wage()
'''
1000000
'''

上一篇:python 10天快速教程 Day6
下一篇:python 10天快速教程 Day8

上一篇 下一篇

猜你喜欢

热点阅读