Python在oop设计中的总结

版权声明:原创 https://blog.csdn.net/qq_41058594/article/details/86712986

今天外边下大雪,足有半米厚,本来想要看完胡寿松的自动控制理论书的第二章(控制系统的数学模型),但是不知道为什么苦于看不进去,所以打开电脑写一篇CSDN,要写就得写自己深刻理解而且还能帮助别人的文章,也就是干货,最近看学弟学妹们也在问我说:"学长面向对象编程是咋回事啊,里面有什么需要掌握的和注意的没啊?"由于本人专业是机械专业,Python全靠自学,有些地方偏于自己的理解,今天在这里写出来,如果有哪些地方不足的话,希望大家提出来。今天就为学弟学妹们写一篇,学长觉得比较注意的地方。在看着一篇文章之前,我建议先看一下对 self 的理解:神秘的self。其实它一点也不神秘!
面向对象编程最重要的就是类和实例。对象是类的实例,类是对象的模板。Python类提供了面向对象编程的所有标准特点!即它允许继承多个基类,派生子类可以重载基类的任何方法,对象可以包括任意数量和任意种类的数据。
1.访问限制
Python规定用两个连续的下划线 “__” 来定义私有变量,所谓的私有变量就是函数或类外部不能访问的变量,自能函数或类内部自己可以调用,例如我们可以这样定义: ‘__name’,在python中我们可以定义相关的方法来实现这些私有变量的访问。而且这些方法还可以对输入变量进行范围的验证和判断。

class Num(object):
    def __init__(self):
        self.num = 10
        self._num = 20
        self.__num = 30
t = Num()
print(t.num)  
print(t._num)
print(t.__num)

在这里插入图片描述

class Num(object):
    def __init__(self):
        self.num = 10
        self._num = 20
        self.__num = 30

    def getnum(self):
          return self.__num
    def setnum(self,num):
          if 0<num<50:
                self.__num = num
          else:
                print('超出范围了!')
t = Num()
t.setnum(6)
print(t.getnum())

在这里插入图片描述
我反正写程序的时候不喜欢写这些变量,有不加下划线的,有加一个下划线的,还有前后各有两下划线的: num, num, num, 他们都有各自不同的用法。num这种的是模块内的私有变量,其子类是无法访问的。
2.继承和多态
重点:继承+重载=多态性
在子类中必须调用父类的__init
方法,而且父类变量必须是self.num这种不带下划线的才可以让子类继承。
3.多重继承 class subClass(Base1,Base2)
这相当于你创建了一个subClass的类,让它同时继承Base1,Base2,一旦你在subClass的实例上有任何隐式动作,Python会回到类的层级结构中去检查Base1,Base2,而且必须要用固定的次序去检查,为了搞定这一点Python用了一个MRO去搜索。
引入多重继承之后,一个新的问题是多个父类之间的继承顺序和方法调用顺序。比如:子类中调用的方法在多个父类中都存在的时候,到底会调用哪个父类的方法?(显然不会把所有父类的方法都调用一遍)
在这里插入图片描述
在这里插入图片描述
还有这样的:
在这里插入图片描述
在这里插入图片描述
通过多重继承,一个子类就可以同时获得多个父类的所有功能。
这里有一篇可以让你了解:
1.深度优先搜索(DFS)
2.广度优先搜索(BFS)
https://blog.csdn.net/five3/article/details/78646978
4.__str__的用法
这是一个常见的方法!

class Num(object):
    def __init__(self,name,num=0.0):
        self.name = name
        self.num = num
    def __str__(self):
        return 'Num类:{},num of {}'.format(self.name,self.num)
t = Num('Panda')
print(t)

在这里插入图片描述
5.元类编程
正常情况下,我们都不会使用到元类。但是这并不意味着,它不重要。假如某一天,我们需要写一个框架,很有可能就需要用到元类。但是,为什么要用它呢?不要它会怎样?在这里我认为使用元类,是要对类进行定制修改。使用元类来动态生成元类的实例。
我认为的是这样:

  • 拦截类的创建
  • 拦截下后,进行修改
  • 修改完后,返回修改后的类

我见过(尚浅)的目前只有:用class关键字定义的类本身是一个对象。基于此,负责产生该对象的类称之为元类(类的类),内置的元类为type。

# 模板
class Mymeta(type):  # 但凡继承了type的类,称之为自定义元类
    def __init__(self,class_name,class_bases, class_dic):
        print(self)
        print(class_name)
        print(class_bases)
        print(class_dic)
 
# People = Mymeta('People',(object,),{……})
class People(object,metaclass=Mymeta):
    def __init__(self, name, age):
        self.name = name
        self.age = age
 
    def score(self):
        print('%s is scoring' % self.name)

可以参考这个:https://cloud.tencent.com/developer/news/215525
6. @staticmethod 与 @propetry
静态方法是一个普通的函数,只不过位于类的命名空间内,在这里我们遇到他或者想要写一个静态方法的话,我们就用装饰器@staticmethod ,这样类和对象都可以调用它,

class Num(object):
    def __init__(self,name,num=0.0):

        self.name = name
        self.num = num
        
    def __str__(self):
        return 'Num类:{},num of {}'.format(self.name,self.num)
    def F(self):
        print('runoob')
    @staticmethod
    def f():
        print('runoob')

        
t = Num('Panda',9)
print(t)
# 实例化后使用静态方法
t.f()
#调用类的F方法
t.F()
# 静态方法无需实例化
Num.f()

采用类中的函数来检查各项属性会很复杂,我们这时候可以使用装饰器@propetry来将方法转化成属性

class People:
    def __init__(self,name):
        self.__name=name

    @property
    def name(self):  #这个功能函数是被property装饰过的
        return self.__name

    @name.setter  #这里就可以以被装饰函数为起始名写一个setter修改接口
    def name(self,val):
        if type(val) is not str:
            print('名字必须是str类型')
            return
        self.__name=val

    @name.deleter  #这里就可以以被装饰函数为起始名写一个deletery删除接口
    def name(self):
        print('不让删除')

obj=People('Panda')

print(obj.name)
obj.name='EGON' #调用了修改接口,修改了name的值
print(obj.name)
del obj.name  #调用删除接口
print(obj.name)

在这里插入图片描述
下一篇我在介绍线程和进程的应用和关系,谢谢各位补充和评论。

猜你喜欢

转载自blog.csdn.net/qq_41058594/article/details/86712986
今日推荐