Python教程

2021-09-0 python基础知识:继承和设计模式

本文主要是介绍2021-09-0 python基础知识:继承和设计模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

      • 1.方法的动态性
      • 2.私有属性和方法
      • 3. @property装饰器
      • 4.练习:私有属性和@property完成控制工资录入
      • 5.面向对象的三大特征
      • 6.继承
        • (1)继承
        • (2)方法重写
        • (3)object根类
        • (4)重写_str_方法
        • (5)super()
      • 7.多态
      • 8. 特殊方法和运算符重载
      • 9.特殊属性
      • 10. 组合
      • 11.设计模式
        • (1)工厂模式
        • (2)单例模式

1.方法的动态性

python中的方法不能重名,定义了多个重名都只有最后一个有效
python是动态语言,可以动态增加方法

class Person:
    def work(self):
        print('work')

def play_game(s):
    print('{0}paly'.format(s))

def work2(s):
    print('好好学习')

Person.play = play_game  # 将play_game这个方法赋给Persen.play
Person.work2 = work2  # 将work2这个方法赋给work2

p = Person()
p.work()
p.play() #Person.play(p),所以这里是不用给参数的
p.work2()

2.私有属性和方法

约定两个下划线开头是私有
方法本质和属性一样,都是对象

class Employee:
    __company  = 'swjtu'      #私有类属性
    def __init__(self,name,age):
        self.name = name
        self.__age = age     #私有属性
    def __work(self):        #私有方法
        print('work hard')
        print('内部调私有属性,年龄{0}'.format(self.__age))


e = Employee('selene',18)

print(e.name)
print(e._Employee__age)    #私有属性外部访问
e._Employee__work()        #私有方法外部访问
print(Employee._Employee__company) #私有类属性外部访问

3. @property装饰器

@property装饰器将一个方法的调用变成一个属性的调用
使用:

class Employee:
    @property
    def salary(self):
        print('salary run...')
        return 100
emp1 = Employee()
print(emp1.salary)#作为属性的调用,不能赋值
 #emp1.salary = 1000会报错

4.练习:私有属性和@property完成控制工资录入

两端代码效果一样

#用私有属性控制薪水录入错误
class Employee2:
    def __init__(self, name, salary):
        self.__name = name
        self.__salary = salary #属性私有

    def get_salary(self):#用这个方法给私有属性赋值
        return self.__salary

    def set_salary(self,salary):
        if 1000<salary<50000:
            self.__salary = salary
        else:
            print('录入错误')

emp2 = Employee2('selene',30000)
print(emp2.get_salary())
emp2.set_salary(2000)
print(emp2.get_salary())
#@property

class Employee3:
    def __init__(self, name, salary):
        self.name = name
        self.__salary = salary #属性私有

    @property
    def salary(self):     #用这个方法给私有属性赋值,相当于get_salary方法
        return self.__salary

    @salary.setter          #针对salar属性的设置,相当于set_salary方法
    def salary(self,salary):
        if 2000<salary<50000:
            self.__salary = salary
        else:
            print('录入错误')
emp3 = Employee3('selene',40000)
print(emp3.salary)
emp3.salary = 10000          #这里可以赋值成功!!!!!!!
print(emp3.salary)

5.面向对象的三大特征

在这里插入图片描述

6.继承

(1)继承

在这里插入图片描述

class Person:
    def __init__(self,name,age):
      self.name = name
      self.__age = age    #父类私有属性,子类继承了但不能直接用
    def say_age(self):
        print('jiecheng')

class Student(Person):
    def __init__(self,name,age,score):
        Person.__init__(self,name,age)   #直接写self.name = name也行,这里是显示调用
        self.score = score

print('Student的继承关系',Student.mro())  #查看Student的继承关系
s = Student('selene',18,100)
s.say_age()       #继承了父类的方法
print(dir(s))     #查看s的所有属性
print('父类非私有属性:',s.name)
print('父类私有属性:',s._Person__age)  #父类的私有属性需要这样调用,不能直接使用
'''
Student的继承关系 [<class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>]
jiecheng
['_Person__age', '__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__', 'name', 'say_age', 'score']
父类非私有属性: selene
父类私有属性: 18
'''

(2)方法重写

子类继承了父类,可以重新定义父类的方法,叫方法重写

class Person:
    def __init__(self,name,age):
      self.name = name
      self.__age = age
    def say_age(self):
        print('print my age:',self.__age)
    def say_name(self):
        print('print my name:', self.name)

class Student(Person):
    def __init__(self,name,age,score):
        Person.__init__(self,name,age)   #直接写self.name = name也行,这里是显示调用
        self.score = score

    def say_name(self):
        print('我的名字是:',self.name)
    def say_age(self):
        print('我的年龄是:',self._Person__age)#name是父类的私有属性

s = Student('selene',18,100)
s.say_name()
s.say_age()
'''
我的名字是: selene
我的年龄是: 18
'''

(3)object根类

class_name.mor()
在这里插入图片描述

object类是其他所有类的父类

(4)重写_str_方法

在这里插入图片描述

#重写object的_str_()
class Person:
    def __init__(self,name):
      self.name = name
    def __str__(self):
        return '名字是:{0}'.format(self.name)


p  = Person('selene')
print(p)

'''
没有_str_时的结果:
<__main__.Person object at 0x000002096990DB08>
有_str_时的结果:
名字是:selene
'''

(5)super()

super()获得父类的定义

class A:
    def say(self):
        print('A:',self)

class B(A):
    def say(self):
        A.say(self)#可以换成super().say(),获得父类的定义对象
        print('B:',self)

B().say()
'''结果:
A: <__main__.B object at 0x00000272A8B11108>
B: <__main__.B object at 0x00000272A8B11108>
'''

7.多态

class Man:
    def dinner(self):
        print('吃饭')
class Chinese(Man):
    def dinner(self):
        print('筷子')
class English(Man):
    def dinner(self):
        print('叉子')

def manEat(m):#形参m需要传一个类
    if isinstance(m,Man):#isinstance()判断对象是否是一个一已知的类型,如isintance(2,int),返回true,且考虑继承
        m.dinner()
    else:
        print('no dinner')

#同一方法调用,由于对象不同可能产生不同的行为
manEat(Chinese())
manEat(English())
'''结果
筷子
叉子
'''

8. 特殊方法和运算符重载

#重载运算符
class Person:
    def __init__(self,name):
      self.name = name

    def __add__(self,other):#重写加法
        if isinstance(other,Person):
            return '{0}--{1}'.format(self.name,other.name)
        else:
            print('不是同类对象,不能相加')
    def __mul__(self,other):#重写乘法
        if isinstance(other,int):
            return self.name*other
        else:
            return '不是整数倍,不能相乘'

p1 = Person('bai')
p2 = Person('selene')
x = p1 + p2
y = p1*3
print(x,y)
'''结果
bai--selene baibaibai
'''

9.特殊属性

在这里插入图片描述

class A:
    def aa(self):
        print('AA')
class B:
    def bb(self):
        print('BB')
class C(A,B):
    def __init__(self,name):
        self.name = name
    def cc(self):
        print('cc')

c = C('selene')
print('获得c的所有属性',dir(c))
print('获得c添加的属性',c.__dict__)
print('获得c的类',c.__class__)
print('获得C的父类(多个)',C.__bases__)
print('获得C的类层次结构',C.mro())
'''结果
获得c的所有属性 ['__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__', 'aa', 'bb', 'cc', 'name']
获得c添加的属性 {'name': 'selene'}
获得c的类 <class '__main__.C'>
获得C的父类(多个) (<class '__main__.A'>, <class '__main__.B'>)
获得c的类 [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
'''

10. 组合

在这里插入图片描述

#使用继承
class A1:
    def say_a1(self):
        print('a1a1')
class B1(A1):
    pass
b1 = B1()
b1.say_a1()


#使用组合
class A2:
    def say_a2(self):
        print('a2a2')
class B2:
    def __init__(self,a):
        self.a = a
a2 = A2()
b2 = B2(a2)
b2.a.say_a2()
'''结果
a1a1
a2a2
'''

11.设计模式

(1)工厂模式

class CarFactory:
    def create_car(self,brand):
        if brand == 'Benz':
            return Benz()
        elif brand =='BMW':
            return BMW()
        elif brand =='BYD':
            return BYD()
        else:
            return 'unknown brand'
class Benz:
    pass
class BMW:
    pass
class BYD:
    pass

factory = CarFactory()
c1 = factory.create_car('BMW')
print(c1)

(2)单例模式

确保一个类就只有一个对象

class MySingleton:
    _obj = None
    __init_flag = True

    def __new__(cls, *args, **kwargs):
        if cls._obj ==None:#若为空,则返回这个对象
            cls._obj = object.__new__(cls)
        return cls._obj

    def __init__(self,name):
        if MySingleton.__init_flag:
            print('init...')
            self.name = name
            MySingleton.__init_flag = False

a = MySingleton('aa')
b = MySingleton('bb')
print(a)
print(b)
'''结果
init...
<__main__.MySingleton object at 0x00000182E01F1588>
<__main__.MySingleton object at 0x00000182E01F1588>
'''
#工厂模式和单例模式的整合
class CarFactory:
    _obj = None
    __init_flag = True

    def create_car(self,brand):
        if brand == 'Benz':
            return Benz()
        elif brand =='BMW':
            return BMW()
        elif brand =='BYD':
            return BYD()
        else:
            return 'unknown brand'

    def __new__(cls, *args, **kwargs):
        if cls._obj ==None:#若为空,则返回这个对象
            cls._obj = object.__new__(cls)
        return cls._obj

    def __init__(self):
        if CarFactory.__init_flag:
            print('init...')

            CarFactory.__init_flag = False

class Benz:
    pass
class BMW:
    pass
class BYD:
    pass

factory = CarFactory()
c1 = factory.create_car('BMW')
c2 = factory.create_car('BYD')
print(c1)
print(c2)

factory2 = CarFactory()
print(factory)
print(factory2)
'''结果
<__main__.BMW object at 0x00000232A81D1C88>
<__main__.BYD object at 0x00000232A81D1C48>
<__main__.CarFactory object at 0x00000232A81D1C08>
<__main__.CarFactory object at 0x00000232A81D1C08>
'''
这篇关于2021-09-0 python基础知识:继承和设计模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!