zoukankan      html  css  js  c++  java
  • python 函数、类

    1、面向对象(oop)

    面向过程:面向处理,更多的是注重计算每一个步骤

    面向对象:认为万事万物皆对象,程序是由多个对象协作共同完成的,能更好的直接代码复用和设计复用

    问题->面向对象分析(OOA)->发现对象->类->用类实例化对象->对象协作完成功能
    
    2、类和对象
    • 类:具有相同特征和行为的对象的集合

    • 对象:具有某些功能和特征的具体事物的抽象,是类的实例

    • 类定义必须使用关键字class,类名一般用大驼峰命名规则:每个单词首字母大写,其他小写

      • class MyDog(object): #python3默认继承自object,可以class Mydog:

        ​ 函数体

    3、类
    class MyDOg(object):
    	num = 100    
    	#类属性   可以通过类名访问,也可以被对象访问.如果成员属性名和类属性名冲突,优先访问成员属性,成员属性屏蔽类属性.
    	
    	def __init__(self,name,age,sex)   #构造函数,一般用于完成对象数据成员设置初值或进行其他必要的		self.name = name	 #初始化工作,不会创建对象,如未提供,python会提供一个默认的构造函数   
    		#成员属性,描述对象的静态特征,其实就是一个变量,作用域属于类。python中成员属性可以在构造函数中添加。成员属性属于对象,每个对象的成员属性的值都不同。
    		self.__age =age # 私有变量  外界不能直接对象.__age调用了,只能通过调用对象的公用方法来访问。
    		self.__sex =sex  #私有变量 
    
    	def bark(self):
    		print('汪汪')      #成员公有方法,作用域在类内,成员方法的第一个参数必须是self,代表调用当前对象,只有对象可以调用
    	def eat(self):
    		print('吃骨头')    #成员公有方法  
        
        #定义一个公开方法,间接访问私有变量    外界通过对象.get_age()
        def get_age(self):
        	return self.__age   
        
        #定义一个公开方法,间接设置私有变量   外界通过对象.set_age()
        def set_age(self,age):
        	self.__age =age
        
        
    #对于私有属性的访问,使用公开方法间接访问的方法太麻烦,python提供了一种便捷语法,属性装饰器,通过属性装饰器,可以很方便的对私有属性访问,属性装饰器可以把方法属性化
        @property              #外界使用 对象.sex
        def sex(self):
        	return self.__sex
         
        @sex.setter   		#外界使用  对象.sex =sex
        def sex(self,sex)
        	self.sex = sex
        	
        	
        	
       #定义一个成员私有方法(双下划线)   
       	def __sleep(self):     
       		print('这是我的地盘')
       	 #外界通过,对象.__sleep()会报错,该方法为私有方法,只能在当前类中被成员公有方法调用。外界通过公有方法获取
       	
       	#定义一个类方法
       	@classmethod
       	def c1(cls):
       		rerurn('我是类方法')
       	
       #定义一个静态方法
       @staticmethod
       def show():
       		return time.time()
      
        
    	
    	def __del__(self):   #析构函数,用来释放对象占用的资源,如果未提供,python将会提供一个默认的析构函数进行必要的清理工作。
    	def __str__(self):
    		return self.name
    	def __repr__(self):
    		return self.__str__()
    
    #将对象转化为字符串,凡是涉及对象向字符串转化的都会调用(`print,str`),返回值是字符串.
    #__repr__作用同__str__,不过是给解释器看的
    	
    		
    		
    dog = MyDog('泰迪')  #对象的创建,对象的实例化 ,定义了一个 类 类型的变量
    print(dog.__dict__)  #__dict__属性可以查看实例属性
    print(dog.__class__) #查看对象的类名
    
    #属性获取
    print(dog.name)   #成员属性的调用:对象。成员属性
    print(dog.get_age())   #获取私有属性age的值go
    dog.set_age(10)        #设置私有属性的值
    print(dog.sex)         #用了@property方法后获取属性值
    dog.sex = sex			#用了@sex.setter方法后修改属性值
    
    
    dog.bark()  #成员方法的调用
    dog.eat().bark() #成员方法的连贯调用
    
    
    • 属性私有化:如果想让类的内部属性不被外界直接访问,可以在这个属性的前面加两个下划线 ,在Python中,如果一个属性的前面出现两个下划线,就表示这个属性只能在当前类中的方法中访问,不能通过对象直接访问,这个变量就被称为私有变量
    单下划线:_age    #受保护的,可以访问的,约定俗称,不要使用它
    双下划线:__age   #私有的
    两边都有双下划线: __age__  #系统内置变量
    
    • 属性装饰器:对于私有属性的访问,使用公开方法间接访问的方法太麻烦,python提供了一种便捷语法,属性装饰器,通过属性装饰器,可以很方便的对私有属性进访问,属性装饰器可以把方法属性化。

      描述器:描述器在监视特定属性的时候很有用,其只在新式类中起作用,种类至少实现了3个特殊的方法__get__, __set__, __delete__中的一个。
      如果一个对象同时定义了 get() 和 set(),它叫做资料描述器(data descriptor)。仅定义了 get() 的描述器叫非资料描述器
      描述器在属性访问时被自动调用。
      调用优先级:
      资料描述器 -> 实例字典 -> 非资料描述器
      
    • 成员私有方法(属于对象)

      • 如果以对一个方法的名字前面加双下划线__,声明该方法为私有方法,只能在当前类中被成员公有方法调用,在外界不能通过对象调用,这就是私有方法。
    • 类方法

      • 使用了装饰器@classmethod,第一个参数是当前类对象,该参数一般约定为cls,通过它来传递类的属性和方法(不能传实例的属性和方法)
      • 调用:实例和类都可以调用
    • 静态方法

      • 使用装饰器@staticmethod。参数没有self和cls,函数体也没有类和对象的属性和方法,就是一个独立的、单纯的函数放在类里了,仅仅托管于某个类的命名空间。
      • 调用:实例对象和类对象都可以调用
      • 其实,我们可以在类外面写一个同样的函数来做这些事,但是这样做就打乱了逻辑关系,也会导致以后代码维护困难
    • 实例成员的动态绑定(了解)

      • 实例的属性和方法都可以动态绑定,也就是在程序运行期间可以给程序增加功能。
      • 给实例动态添加的属性只属于这个实例,其他对象没有该属性
      • 使用__slot__限制属性的动态绑定
      • 给类绑定成员方法,所有对象都可以使用
    4、类的三大特性
    • 封装

      • 隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读取和修改的访问级别。
      • 类本身就是一种封装,通过类将数据(属性)和行为(方法)相结合,提供外部接口,以特定的权限来使用类的成员。成员私有化是实现封装的手段。
    • 继承

      • 所谓继承就是使现有的类无需编码就可以拥有基类的方法和属性

      • 被继承的类称为父类,基类,超类,继承的类称之为子类,派生类。

      • 继承的优点:可以简化代码,减少冗余度

        ​ 提高了代码的可维护性,扩展性

        ​ 提高了代码的安全性

      • 单继承:就是只继承一个父类,子类会继承父类所有的属性和方法

        • 继承自父类的私有成员在子类中无法直接使用,要用原父类的方法调用。因为私有方法,它现在已经不在父类中了,在子类

        • 子类方法和父类方法重名,通过子类对象调用的是子类方法(重写覆盖)

          构造函数的继承
          class Mydog(Animal)
          	def __init__(self,name,age,gender)
          		父类名.__init__(self,name,age)
          		self.gender = gender
          		#或者
          		super(Mydog,self).__init__(name,age)  #实参列表不要带self
          		self.gender =gender
          		#或者
          		super().__init__(name,age)
          		self.gender =gender
          
      • 多继承:继承自多个父类,如果两个父类中有同名方法,调用的前面父类的方法,前面父类的方法会遮蔽后面的

        • class MyDog(Animal,Pet):
    • 多态

      • 多态指的是根据对象或类的不同而表现出不同的行为,
      • 不同的子类对象调用相同的父类方法,产生了不同的执行结果
      • 多态好处:
        • ​ 提高了方法调用的灵活性
    • 鸭子类型: 鸭子类型就是不关系对象的类型,只关心对象的行为

      • 如果一只鸟 走起来像鸭子,叫起来也像鸭子,那么这只鸟就可以被称为鸭子
      • 鸭子类型是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由"当前方法和属性的集合"决定。
      • 比如如果一个对象实现了__getitem__方法,那python的解释器就会把它当做一个collection,就可以在这个对象上使用切片,获取子项等方法;如果一个对象实现了__iter__next方法,python就会认为它是一个iterator,就可以在这个对象上通过循环来获取各个子项。
    5、魔术方法
    • 魔术方法就是一个类的特殊方法,和普通方法唯一的不同时,普通方法需要调用!而魔术方法由系统自动调用。

    • 常用魔术方法

      1.__init__

      初始化魔术方法
      触发时机:初始化对象时触发(不是实例化触发,但是和实例化在一个操作中)
      p1 = Person()
      p1对象   实例化对象p1   p1 实例
      参数:至少有一个self,接收对象
      返回值:无
      作用:初始化对象的成员
      

      2.__new__

      实例化魔术方法  类方法
      触发时机: 在实例化对象时触发
      参数:至少一个cls 接收当前类
      返回值:必须返回一个对象实例
      作用:实例化对象
      注意:实例化对象是Object类底层实现,其他类继承了Object的__new__才能够实现实例化对象。
      没事别碰这个魔术方法,先触发__new__才会触发__init__ 
      class Dog:
          def __new__(cls, *args, **kwargs):
              print('new方法在执行')
             // return super().__new__(cls,*args, **kwargs)   #必须通过父类的__new__创建对象
              return object.__new__(cls,*args, **kwargs)
              
          def __init__(self,name,age):
              self.name = name
              self.__age = age
              print('init方法在执行')
      

      3.__del__

      析构魔术方法
      触发时机:当对象没有用(没有任何变量引用)的时候被触发
      参数:一个self 
      返回值:无
      作用:在销毁对象时回收资源
      注意:del不一定会触发当前方法,只有当前对象没有任何变量引用时才会触发
      

      4.__call__

      调用对象的魔术方法
      触发时机:将对象当作函数调用时触发,方式: 对象()
      参数:至少一个self接收对象,其余根据调用时参数决定
      返回值:根据情况而定
      作用:可以将复杂的步骤进行合并操作,减少调用的步骤,方便使用
      注意:无
      

      5.__len__

      触发时机:使用len(对象) 的时候触发
      参数:一个参数self
      返回值:必须是一个整型
      作用:可以设置为检测对象成员个数,但是也可以进行其他任意操作
      注意:返回值必须必须是整数,否则语法报错,另外该要求是格式要求。
      

      6.__str__

      触发时机:使用print(对象)或者str(对象)的时候触发
      参数:一个self接收对象
      返回值:必须是字符串类型
      作用:print(对象时)进行操作,得到字符串,通常用于快捷操作
      注意:无
      

      7.__repr__

      触发时机:在使用repr(对象)的时候触发
      参数:一个self接收对象
      返回值:必须是字符串
      作用:将对象转使用repr化为字符串时使用,也可以用于快捷操作
      

      8.__bool__

      触发时机: 使用bool(对象)的时候触发
      参数:一个self接收对象
      返回值:必须是布尔值
      作用:根据实际情况决定,可以作为快捷方式使用
      注意:仅适合于返回布尔值的操作
      

      9.__format__

      触发时机:使用字符串.format(对象)时候触发
      参数:一个self接收对象,一个参数接收format的{}中的格式,例如:>5
      返回值:必须是字符串
      作用:设置对象可以作为format的参数,并且自定义对象格式化的规则
      注意:无
      

      10.__eq__

      比较运算符重载:__eq__,__ge__,__le__,__gt__,__ne__
      
    6、常用内建函数
    • issubclass(sub,sup)

      如果sub是sup的子类,返回True,否则返回False。sub和sup必须是类

    • isinstance(obj,class)

      如果obj是class的对象或子类对象,返回Ture,否则返回False,属性必须是公有的才能判断。

      isinstance与type区别
      	isinstance考虑继承关系,isinstance(对象或子类,父类) True
      	type不考虑继承关系      type(子类对象或子类) = 父类  False				  	
      
    • hasattr(object,name)

    判断对象是否具有指定属性(name),有则返回True,否则返回False

    • getattr(object,name[,default])

    获取object对象的属性值

    • setattr(object,name)

      设置对象的属性值,属性必须存在

    • callable(object)

      判断一个对象是否可调用

    • dir(obj/class)

      显示类或对象属性、方法等详细信息

    • super(obj,self)

    调用父类(超类)的一个方法

    7.装饰器
    • 装饰器就是用于拓展原来函数功能的一种函数,在不改变源代码的情况下,动态的添加功能,经常用在插入日志、性能测试。
      写代码要遵循开放封闭原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即:
      •  封闭:已实现的功能代码块   
      •  开放:对扩展开发
      
    • #无参装饰器
        def decorator(func):
        	print('我被调用了')
        	@wraps(func)         #加不加都可以,减少装饰器带来的一些副作用,如函数名等属性变化
            def wrapper(*args,**kwargs):    
                print('任务开始')
                r=func(*args,**kwargs)
                print('任务完成')
            return  wrapper
      
        @decorator
        def f1():
            print(123)
        f1()     
        f1()
        #同一个函数如f1执行两次,装饰器中print('我被调用了')只会执行一次,在函数调用第一次执行。
      
        @decorator
        def f2(a,b):
            print(a,b)    
        f2(1,2)
        f2(1,2)
    • #有参装饰器
      def decorator(number): 
        	print(number)
            def decorator1(func): 
                def wrapper(*args, **kwargs):
                    print('--------->开始')
                    r=func(*args, **kwargs)
                    print('--------->结束')
                    return r
                return wrapper
            return decorator1
      
        #比无参装饰器多套了一层
      @decorator(10)
      def show():
            rerurn '调用show函数'
            
      
      a=show()
      print(a)
      
        # 如果装饰的函数有返回值,装饰器的内层函数也要有返回值,从而保证装饰后的函数与原函数保持一致性
      
    • #多个装饰器
      def decorator1(func):
          print('我是装饰器1')
      
          def wrapper(*args, **kwargs):
              func(*args, **kwargs)  # func =  house
              print('铺地板')
      
          return wrapper
      
      
      def decorator2(func):  # func = 第一层wrapper
          print('我是装饰器2')
      
          def wrapper(*args, **kwargs):
              func(*args, **kwargs)
              print('买衣柜')
      
          return wrapper
      
      
      @decorator2
      @decorator1
      def house():
          print('------》毛坯房')
      
      
      house()
      # 多层装饰器:谁离原函数最近先执行哪个装饰器,将第一层装饰器的返回结果传给第二层装饰器。
      最后:原函数得到的地址是第二层函数的返回值wrapper
      
      # 执行结果
      我是装饰器1
      我是装饰器2
      ------》毛坯房
      铺地板
      买衣柜
      
      
      
    
    ##### 8.设计模式
    
    - 单例设计模式的实现
      
    - 基于`__new__`方法实现
      
      ```python
      class Singleton:
      
          def __new__(cls, *args, **kwargs):
              if not hasattr(cls,"_instance"):
              	cls.instance = object.__new__(cls)
              return cls._instance	
    
    • 基于装饰器

      def singleton(cls):
      	_instance = {}  #创建一个字典,一会字典中键就是类,值就是对象
      	
      	def _singleton(*args,**kwargs):
      		if cls not in _instance:
      			_instance[cls] = cls(*args,**kwargs)  #类创建对象,赋值给字典_instance,字典键cls唯一,所以一个类只有一个键
      		return _instance[cls]
      	return _singleton
      		
      @singleton
      class A:
      	def __init__(self,name):
      		self.name = name 
      
      a1 = A(2)
      a2 =A(3)
    • 基于python模块

      python模块就是天然的单例模式,因为模式在第一次导入时,会生成.pyc文件。当第二次导入时,就会直接加载.pyc文件,而不会再次执行模块代码,因此我们只需把相关的函数和数据定义在一个天然模块中,就可以获得一个单例对象了。
      
      新建一个a.py文件
      class Singleton:
      	pass
      singleton =Singleton()
      
      #使用
      from a.py import singleton
      
    • 基于__metaclass__ 它是在类创建过程中

    • 设计模式共23种,主要分三个类型 :创建型、结构型和行为型

      • 创建型

        Singleton 单例模式

        Abstract Factory 抽象工厂

        Factory Method 工厂方法

        Prototype 原型模式

      • 行为型

        iterator 迭代器模式

        Observer 观察者模式

        Visitor 访问者模式

        Mediator 中介者模式

      • 结构型

        composite 组合模式

        decrator 装饰模式

        Bridge 桥模式

        Flyweight 享元模式

    9 、函数重载
    • python不需要函数重载,函数重载是为了解决两个问题
      两个函数仅仅是参数类型 和 参数个数多少。
      python参数可以是任意类型的,参数个数可以设置为缺省。
  • 相关阅读:
    关于学习方法
    ES6的异步操作
    Promise对象的基本用法
    Generator函数(三)
    Generator函数(二)
    Generator函数(一)
    ES6 Set结构和Map结构(上)
    mybatis02--增删改查
    myBatis01
    监听器
  • 原文地址:https://www.cnblogs.com/-min/p/12833249.html
Copyright © 2011-2022 走看看