Python教程

Python基础 - 09面向对象特性

本文主要是介绍Python基础 - 09面向对象特性,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Python09 - 面向对象特性

封装、继承和多态 

一、封装

# 私有化
class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return '姓名:{}, 年龄:{}'.format(self.name, self.age)

s1 = Student('张三', 18)
print(s1)               # 姓名:张三, 年龄:18
s1.age = -9
print(s1)               # 姓名:张三, 年龄:-9

  

# 封装:    私有化属性, 定义公有set和get方法
# __属性:  将属性私有化,访问访问仅仅限于类中; 隐藏属性不被外界随意修改
class Student:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age
        self.__score = 60

    def setAge(self, age):
        if 0 < age < 120:
            self.__age = age
        else:
            print('年龄不准确')

    def getAge(self):
        return self.__age

    def __str__(self):
        return '姓名:{}, 年龄:{}'.format(self.__name, self.__age)

s2 = Student('张三', 18)
print(s2)                  # 姓名:张三, 年龄:18
s2.age = -9
print(s2)                  # 姓名:张三, 年龄:18
s2.setAge(-9)
print(s2)                  # 年龄不准确 \n 姓名:张三, 年龄:18

  

print(dir(Student))
'''
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', 
'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', 
'__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'getAge', 'setAge']
'''

print(dir(s2))
'''
['_Student__age', '_Student__name', '_Student__score', 
'__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', 
'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', 
'__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'getAge', 'setAge']
'''

print(__name__)           # __main__
#print(s2.__name)         # AttributeError: 'Student' object has no attribute '__name'
print(s2._Student__name)  # 张三

print(s2.__dir__())
'''
['_Student__name', '_Student__age', '_Student__score',
'__module__', '__init__', 'setAge', 'getAge', '__str__', '__dict__', 
'__weakref__', '__doc__', '__repr__', '__hash__', '__getattribute__', 
'__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', 
'__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__',
 '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
'''

  

私有化处理: 装饰器

# 装饰器
class Student:
    def __init__(self, name, age):
        self.name = name
        self.__age = age

    # def setAge(self, age):
    #     if 0 < age < 120:
    #         self.__age = age
    #     else:
    #         print('年龄不准确')
    #
    # def getAge(self):
    #     return self.__age

    @property       # 先有getXXX
    def age(self):
        return self.__age

    @age.setter     # 再有setXXX
    def age(self, age):
        if 0 < age < 120:
            self.__age = age
        else:
            print('年龄不准确')

    def __str__(self):
        return '姓名:{}, 年龄:{}'.format(self.name, self.__age)

s3 = Student('悟空',500)
s3.name = '孙悟空'
print(s3.name)              # 孙悟空

s3.age = 130                # 年龄不准确
print(s3.age)               # 500
print(s3.__dir__())
'''
['name', '_Student__age', 
'__module__', '__init__', 'age', '__str__', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__getattribute__',
'__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', 
'__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
'''

  

二、继承

class Person:
    def __init__(self, name, age):
        print('**** Person的init初始化')
        self.__name = name
        self.__age = age

    def setName(self, name):
        self.__name = name

    def getName(self):
        return self.__name

    def setAge(self, age):
        self.__age = age

    def getAge(self):
        return self.__age

    def eat(self):
        print(self.__name + '正在吃饭...')

    def run(self):
        print(self.__name + '正在跑步...')

class Student(Person):
    pass

class Teacher(Person):
    pass

s1 = Student('小花',14)
s1.run()                   # 小花正在跑步...
t1 = Teacher('王老师',45)
t1.run()                   # 王老师正在跑步...

  

class Student(Person):
    def __init__(self, name, age, course):
        print('---> student的init')
        super().__init__(name, age)
        self.course = course

    def study(self, course):
        print('{}正在学习{}课程'.format(self.getName(), course))

    def eat(self, food):
        super().eat()
        print(self.getName() + '正在吃饭..., 喜欢吃:' + food)

class Employee(Person):
    def __init__(self, name, age, salary, manager):
        super().__init__(name, age)
        self.salary = salary
        self.manager = manager

s2 = Student('Tom', 27, '三年五班')
s2.run()
s2.study('数学')
'''
---> student的init
**** Person的init初始化
Tom正在跑步...
Tom正在学习数学课程
'''

  

1. 如果类中不定义__init__, 调用父类 super class 的 __init__
2. 如果类继承父类时也需要自定义自己的__init__, 需要在当前类的__init__调用父类的__init__
3. 调用父类__init__:  super().__init__(参数)    super(类名,对象).__init__(参数)
4. 如果父类有eat()方法,子类也定义了eat()方法,默认搜索原则:先找当前类,再找父类
5. s2.eat()  重写(覆盖/override): 父类提供的方法不能满足子类的需求,子类中定义一个同名方法

s2.eat('西瓜') 
# Tom正在吃饭...    
# Tom正在吃饭..., 喜欢吃:西瓜

 

多重继承,inspect.getmro() 查看继承顺序  

经典类:  从左向右, 深度优先

新式类:  广度优先

class Base:
    def test(self):
        print('--Base--test--')

class A(Base):
    def test(self):
        print('--A--test--')

class B(Base):
    def test(self):
        print('--B--test--')

class C(Base):
    def test(self):
        print('--C--test--')

class D(A, B, C):
    pass

class E(B, C, A):
    pass

c = C()
c.test()  # --C--test--

d = D()
d.test()  # --A--test--

e = E()
e.test()  # --B--test--

import inspect
print(inspect.getmro(D))
'''
(<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, 
<class '__main__.Base'>, <class 'object'>)
'''

print(inspect.getmro(E))
'''
(<class '__main__.E'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, 
<class '__main__.Base'>, <class 'object'>)
'''

  

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

class B:
    def __init__(self):
        print('B')

class C(A):
    def __init__(self):
        print('C')
        super(C, self).__init__()

class D(A):
    def __init__(self):
        print('D')
        super(D, self).__init__()

class E(C, B):
    def __init__(self):
        print('E')
        super(E, self).__init__()

class F(C, D, B):
    def __init__(self):
        print('F')
        super(F, self).__init__()

class G(D, B):
    def __init__(self):
        print('G')
        super(G, self).__init__()

if __name__ == '__main__':
    import inspect

    g = G()
    print(inspect.getmro(G))
    f = F()
    print(inspect.getmro(F))
    e = E()
    print(inspect.getmro(E))
'''
G
D
A
(<class '__main__.G'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)

F
C
D
A
(<class '__main__.F'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)

E
C
A
(<class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
'''

  

三、多态

class Pet:
    role = '宠物'

    def __init__(self, nickname, age):
        self.nickname = nickname
        self.age = age

    def show(self):
        print('昵称:{}, 年龄:{}'.format(self.nickname, self.age))

class Cat(Pet):
    role = '猫'

    def catch_mouse(self):
        print('抓老鼠...')

class Dog(Pet):
    role = '狗'

    def watch_house(self):
        print('看家...')

class Tigger:
    role = '老虎'

    def eat(self):
        print('老虎吃人...')

class Person:
    def __init__(self, name):
        self.name = name

    # pet既可以接收cat,也可以是dog, trigger
    def feed_pet(self, pet):
        print('{}喜欢养宠物:{}'.format(self.name, pet.role))
    # 对pet参数进行判断,是不是类的对象,或者该类子类的对象
    def feed_pet2(self, pet):
        if isinstance(pet, Pet):
            print('{}喜欢养宠物:{}, 昵称:{}'.format(self.name, pet.role, pet.nickname))
        else:
            print('不是宠物,不能养...')

cat = Cat('花花', 2)
dog = Dog('旺财', 1)
person = Person('管家')
person.feed_pet(cat)              # 管家喜欢养宠物:猫

tigger = Tigger()

person1 = Person('阿拉伯人')
person1.feed_pet(tigger)          # 阿拉伯人喜欢养宠物:老虎

person2 = Person('俄罗斯人')
person2.feed_pet2(tigger)         # 不是宠物,不能养...
person2.feed_pet2(dog)            # 俄罗斯人喜欢养宠物:狗, 昵称:旺财

  

四、单例模式

# 单例模式
class Student:

    def study(self, course):
        print('{}正在学习{}课程'.format(self.name, course))

s = Student()
s1 = Student()
s2 = Student()
print(s)        # <__main__.Student object at 0x000000C59D6931F0>
print(s1)       # <__main__.Student object at 0x000000C59D68F370>
print(s2)       # <__main__.Student object at 0x000000C59D68F3A0>

  

class Singleton:
    __instance = None   # 私有化

    def __new__(cls):   # 重写__new__  
        print('----> __new__')
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
            return cls.__instance
        else:
            return cls.__instance

    def show(self, n):
        print('------->show', Singleton.__instance, n)

singleton = Singleton()   # ----> __new__
print(singleton)          # <__main__.Singleton object at 0x000000835F74F220>

singleton2 = Singleton()  # ----> __new__
print(singleton2)         # <__main__.Singleton object at 0x000000835F74F220>

singleton3 = Singleton()  # ----> __new__
print(singleton3)         # <__main__.Singleton object at 0x000000835F74F220>

singleton.show(5)         # ------->show <__main__.Singleton object at 0x00000085247DF1F0> 5
singleton2.show(7)        # ------->show <__main__.Singleton object at 0x00000085247DF1F0> 7

  

 

这篇关于Python基础 - 09面向对象特性的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!