zoukankan      html  css  js  c++  java
  • Python 面向对象编程之进阶使用

    我们在https://www.cnblogs.com/yinsedeyinse/p/9976280.html中学习了面向对象的编程方法。现在学习他的进阶用法。

    1. 静态方法

    2. 类方法

    3. 属性方法

    4. 类的特殊功能方法

    静态方法、类方法以及属性方法:我们先定义一个类,在类里定义一个方法

     1 class Person(object):
     2     def  __init__(self,name):
     3         self.name = name
     4        5 
     6     def eat(self,food):
     7         print("%s is eating %s"%(self.name,food))
     8 
     9 
    10 peaple = Person("Jack")
    11 peaple.eat("cake")
    Jack is eating cake
    运行结果

    这个是常规的类的使用,一切正常,

    然后我们把方法前加一个@staticmethod,把eat()转变成一个静态方法,运行一下,程序报错了!

    TypeError: eat() missing 1 required positional argument: 'food'
    运行结果

    发现少了个参数,我们把程序简化一下,看看是怎么回事!

    1 class Person(object):
    2     def  __init__(self,name):
    3         self.name = name
    4         self.__food = None
    5     @staticmethod
    6     def eat(self):
    7         print(self.name)
    8 peaple = Person("Jack")
    9 peaple.eat()
    TypeError: eat() missing 1 required positional argument: 'self'
    运行结果

    再改一下

    1 class Person(object):
    2     def  __init__(self,name):
    3         self.name = name
    4         self.__food = None
    5     @staticmethod
    6     def eat(name,food):
    7         print("%s is eating %s"%(name,food))
    8 peaple = Person("Jack")
    9 peaple.eat("David","cake")
    David is eating cake
    运行结果

    可以发现,静态方法无法调用类里的属性了!

    所以,静态方法就是实际上已经跟类没什么关系了,也就是名义上归类管理。在方法内无法调用类或实例里的任何属性。还有个用法相当于类的工具包(高级语法,有机会再说!)。

    我们再看看类方法,在方法前加上@classmethod运行一下

    1 class Person(object):
    2     def  __init__(self,name):
    3         self.name = name
    4     @classmethod    #类方法
    5     def eat(self,food):
    6         print("%s is eating %s"%(self.name,food))
    7 peaple = Person("Jack")
    8 peaple.eat("cake")
    AttributeError: type object 'Person' has no attribute 'name'
    运行结果

    提示没有“name”的变量,为什么呢?我们把name定义成类变量试一试。

    1 class Person(object):
    2     name = "Jeff"
    3     def  __init__(self,name):
    4         self.name = name
    5     @classmethod
    6     def eat(self,food):
    7         print("%s is eating %s"%(self.name,food))
    8 peaple = Person("Jack")
    9 peaple.eat("cake")
    Jeff is eating cake
    运行结果

    类变量只能访问类变量,不能访问实例变量。

    属性方法

    1 class Person(object):
    2     def __init__(self,name):
    3         self.name = name
    4     @property
    5     def eat(self):
    6         print("%s is eating"%self.name)
    7 p1 = Person("Jack")
    8 p1.eat  #这里的p1.eat调用的是属性,不是方法
    Jack is eating
    运行结果

    在这个方法前加了@property,就把原来的方法改成了属性方法。在实例化后,不能用访问方法的形式(p1.eat())去访问,而要用属性的形式(p1.eat)。

    但是有个问题,如果在属性方法里有参数需要传递的话,就要用到装饰器了!

     1 class Person(object):
     2     def __init__(self,name):
     3         self.name = name
     4         self.__food = None      #先定义个私有属性
     5     @property
     6     def eat(self):
     7         print("%s is eating %s"%(self.name,self.__food))
     8     @eat.setter                 #定义装饰器
     9     def eat(self,food):
    10         print("set to food:",food)
    11         self.__food = food
    12 p1 = Person("Jack")
    13 p1.eat
    14 p1.eat = "bread"            #对属性方法赋值
    15 p1.eat
    Jack is eating None
    set to food: bread
    Jack is eating bread
    运行结果

    完成效果,如果我们想把属性方法删除,用一般的删除方法是不行的

    1 del p1.eat

    这时候我们必须在类里重新定义个方法

     1 class Person(object):
     2     def __init__(self,name):
     3         self.name = name
     4         self.__food = None      #先定义个私有属性
     5     @property
     6     def eat(self):
     7         print("%s is eating %s"%(self.name,self.__food))
     8     @eat.setter                 #定义装饰器
     9     def eat(self,food):
    10         print("set to food:",food)
    11         self.__food = food
    12     @eat.deleter                #删除方法
    13     def eat(self):
    14         del self.__food
    15         print("已删除!")
    16 p1 = Person("Jack")
    17 p1.eat
    18 p1.eat = "bread"            #对属性方法赋值
    19 p1.eat
    20 del p1.eat                  #删除属性方法
    21 p1.eat                      #重新调用测试一下
    Jack is eating None
    set to food: bread
    Jack is eating bread
    已删除!
    Traceback (most recent call last):
      File "D:/python/week7/属性方法.py", line 45, in <module>
        p1.eat
      File "D:/python/week7/属性方法.py", line 31, in eat
        print("%s is eating %s"%(self.name,self.__food))
    AttributeError: 'Person' object has no attribute '_Person__food'
    运行结果

     那有什么用呢?几个例子,航空公司都能提供航班状态,而其他的三方运营商需要调用这个值,显而易见的是运营商不能修改航班状态

     1 class Flight(object):
     2     def __init__(self,name):
     3         self.name = name
     4 
     5     def checking_status(self):
     6         print("checking flight %s status"%self.name)
     7     @property
     8     def flight_status(self):
     9         status = self.checking_status()
    10         if status == 0:
    11             print("flight is caceled!")
    12         elif status == 1:
    13             print("flight is arrived!")
    14         elif status == 2:
    15             print("flight has departured already!")
    16         else:
    17             print("cannot confirm the flight status,please check later!")
    18 
    19     @flight_status.setter    #航空公司返回航班的状态关键字
    20     def flight_status(self,status):
    21         status_dic = {
    22             0:'caceled',
    23             1:'arrived',
    24             2:'departured'
    25         }
    26 
    27     @flight_status.deleter  #删除该航班状态
    28     def flight_status(self):
    29         print("status is deleted!")
    30 f = Flight("MU2388")           #要查的航班编号
    31 f.flight_status = 1             #航空公司每次只返回一个值描述出该航班状态
    32 f.flight_status                 #其他的运营商直接访问属性的值,而不能改变其状态 

    现在来看一看一些类的特殊方法:

    1.__doc__  获取类的描述信息

    1 # Author:Aaron
    2 class People():
    3     '''
    4     该类描述了人类
    5     '''
    6     def func1(self):
    7         pass
    8 print(People.__doc__)
    C:UsersAaronAnaconda3python.exe D:/python/week7/类的特殊成员.py
    该类描述了人类
    运行结果

    在对类进行描述时,只能用‘’‘——’‘’来注释,用#注释时返回值为None。并且__doc__可以在不进行实例化时直接对类使用,也可以对实例使用。

     2.__module__和__class__

    1 from lib.aa import C
    2 obj = C()
    3 print(obj.__module__) #输出lib.aa,即为输出该功能所属模块
    4 print(obj.__class__)  #输出lib.aa.C,即为输出该类

    在大量调用模块时,用这两个方法可以显示调用的类是属于那个模块的。

    3.__call__

    在实例后加(),执行功能

    1 class Dog():
    2     def __call__(self, *args, **kwargs):
    3         print("__call__的用法")
    4 d1 = Dog()
    5 d1()
    C:UsersAaronAnaconda3python.exe D:/python/week7/类的特殊成员.py
    __call__的用法
    运行结果

    在功能中,可以传递各种参数。

    4.__dict__查看类或对象中的所有成员

     1 class People():
     2     def __init__(self,name,age,sex):
     3         self.name = name
     4         self.age  = age
     5         self.sex  = sex
     6     def eat(self):
     7         pass
     8     def talk(self):
     9         pass
    10 
    11 p1= People("Jack",22,"male")
    12 print(p1.__dict__)      #打印所有实例属性,不包括类属性
    13 print(People.__dict__)  #打印所有类属性,不包括实例属性
    C:UsersAaronAnaconda3python.exe D:/python/week7/类的特殊成员.py
    {'name': 'Jack', 'age': 22, 'sex': 'male'}
    {'__module__': '__main__', '__init__': <function People.__init__ at 0x00000243C1246510>, 'eat': <function People.eat at 0x00000243C1246598>, 'talk': <function People.talk at 0x00000243C1246620>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
    运行结果

    以一个字典的形式把类或实例的方法打印出来,作用是在程序运行以后,如果有新加的属性,可以用这个方式查看。

     5.__str__   可以直接用print打印字符串

    1 class People():
    2     def __init__(self,name):
    3         self.name = name
    4     def __str__(self):
    5         return 'obj:%s'%self.name
    6 
    7 p = People('Jeck')
    8 print(p)
    C:UsersAaronAnaconda3python.exe D:/python/week7/类的特殊成员.py
    obj:Jeck
    运行结果

     django中常用的用法,可以用来返回实例。

    6. __getitem__,__setitem__,__delitem__

    可以把一个字典封装成一个实例(类),用字典的方式添加类的属性等。然后控制字典的权限。用户可以访问这个字典其实是访问了一个类,但可以对用户进行权限控制。

  • 相关阅读:
    WebService 创建
    SAP WebService 概览
    Web Dynpro 架构
    Web Dynpro 配置
    ALE 概览
    Web Dynpro 概览
    IDOC 概览
    WebService 调用
    Windows Server 2016 域控制器搭建NTP服务,并分发NTP策略
    在ESXi 7.0中安装 MacOS Monterey
  • 原文地址:https://www.cnblogs.com/yinsedeyinse/p/10023183.html
Copyright © 2011-2022 走看看