zoukankan      html  css  js  c++  java
  • python M3 面向对象

    静态方法

    截断了类和方法的内在联系。 只是名义上归类管理,实际上在静态方法里访问不了类或者实例中的任何属性。

    class Dog(object):
    
        def __init__(self, name):
            self.name = name
    
        @staticmethod    # 静态方法截断了类和方法的联系。 和在类外设置函数是一样的。
        def eat(self):
            print('%s is earting bum ' %(self.name))
    
    d = Dog("Rory")
    d.eat()
    

    返回错误结果如下:

    Traceback (most recent call last):
      File "/Users/PycharmProjects/learningnote/moduel3/OPP进阶 - 静态方法.py", line 18, in <module>
        d.eat()
    TypeError: eat() missing 1 required positional argument: 'self'
    

    类方法

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

    class Dog(object):
    
        name = "marlynda"
    
        def __init__(self, name):
            self.name = name
    
        @classmethod  # 类方法
        def eat(self):
            print('%s is earting bum' % self.name)
    
    d = Dog("Rory")
    d.eat()  # 在类方法下, 调用的self.name是类变量
    

    返回结果:

    marlynda is earting bum
    

    属性方法

    @property 将一个方法变成一个静态属性,即调用是不用加()

    class Dog(object):
    
        name = "marlynda"
    
        def __init__(self, name):
            self.name = name
    
        @property
        def eat(self):
            print('%s is earting bum' % self.name)
    
    d = Dog("Rory")
    d.eat
    

    当该方法原来有参数时,改写方式应该如下:

    class Dog(object):
    
        name = "marlynda"
    
        def __init__(self, name):
            self.name = name
            self.__food = None   # 3. 添加私有属性__food
    
        @property          # 1. 设置属性方法,将方法转变为静态属性
        def eat(self):
            print('%s is eating %s' % (self.name, self.__food))
    
        @eat.setter        # 2. 另增加一个同为eat的方法,并增加参数food
        def eat(self, food):
            print("set the food:", food)
            self.__food = food    # 4. 传入参数,更新私有属性__food
    
        @eat.deleter       # 5. 作为属性, 单纯调用 del d.eat,是删不掉。需要再写个@eat.deleter
        def eat(self):
            del self.__food
            print("删完了")
    
    d = Dog("Rory")
    
    d.eat
    d.eat = "bum"
    d.eat
    d.eat = "beef"
    d.eat
    
    del d.eat
    

    返回结果

    Rory is eating None
    set the food: bum
    Rory is eating bum
    set the food: beef
    Rory is eating beef
    删完了
    

    属性方法在实际情况中,比较有用。很多场景中是不能简单通过定义静态属性来实现的。

    比如,类似像飞常准这样的平台,获取一个航班的当前状态(到达,延迟,取消,还是飞走等), 需要经历以下几步:

    1. 链接航空公司提供的API接口:可能是json, xml等
    2. 对查询结果进行解析
    3. 返回结果给你的用户

    获取这些status其实是一系列动作的结果,但是客户不关心,他们只需要这系列动作后的结果即可。

    class Fight(object):
        def __init__(self, name):
            self.flight_name = name
    
    
        def checking_status(self):
            print('checking flight %s status' % self.flight_name)
            return 1
    
        @property
        def flight_status(self):
            status = self.checking_status()
            if status == 0:
                print('flight got cancelled...')
            elif status == 1:
                print("flight has arrived...")
            elif status == 2:
                print("flight has departured already...")
            else:
                print("cannot confirm the flight status... please check later")
    
        @flight_status.setter
        def flight_status(self, status):
            print("flight %s has change status to %s" %(self.flight_name, status))
    
    f = Fight("CA980")
    f.flight_status
    f.flight_status = "2"
    f.flight_status
    

    返回信息

    checking flight CA980 status
    flight has arrived...
    flight CA980 has change status to 2
    checking flight CA980 status
    flight has arrived...
    

    特殊成员方法

    特殊方法一般主要实现模拟标准类型重载操作符

    1. __doc__

    现实类的描述信息, 调用如下 print(Foo.__doc__)

    2. __module__ __class__

    __module__ 表示当前操作的对象在哪个模块 __class__ 表示当前操作的对象的类是啥么

    3. __init__

    4. __del__

    5. __bases__

    显示其父类的集合的元祖

    5. __call__

    对象后面加括号,促发执行,即对象() 或者 类()()。比较重要

    class Foo:
        def __init__(self):
            pass
    
        def __call__(self, *args, **kwargs):
            print
            '__call__'
    
    
    obj = Foo()  # 执行 __init__
    obj()  # 执行 __call__
    

    6. __dict__

    查看类或者对象中的所有成员

    class Dog(object):
    
        def __init__(self, name):
            self.name = name
    
        def eat(self):
            print('%s is earting bum ' %(self.name))
    
    d = Dog("Rory")
    
    print(Dog.__dict__)  # 打印类里的所有属性,不包括实例属性
    # 返回:{'__module__': '__main__', '__init__': <function Dog.__init__ at 0x103121840>, 'eat': <function Dog.eat at 0x1031218c8>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__weakref__': <attribute '__weakref__' of 'Dog' objects>, '__doc__': None}
    print(d.__dict__)    # 打印所有实例属性,不包括类属性
    # 返回:{'name': 'Rory'}
    

    7. __str__

    如果一个类中定义了__str__方法, 那么打印对象时,默认输出该方法的返回值。 不打__str__的话,会返回内存地址。 django中用的比较多。

    class Dog(object):
    
        def __init__(self, name):
            self.name = name
    
        def eat(self):
            print('%s is earting bum ' %(self.name))
    
        def __str__(self):
            return "<obj: %s>" % self.name
    

    8. __getitem__, __setitem__, __delitem__

    用于索引操作,如字典,以上分别表示获取、设置、删除数据。多数情况用不到。 在封装一个底层的时候,经常会用到,让客户以为在调用一个字典。

    class Foo(object):
    
        def __init__(self, ):
            self.data = {}
    
        def __getitem__(self, key):
            print('__getitem__', key)
            return self.data.get(key)
    
        def __setitem__(self, key, value):
            print("__setitem__", key, value)
            self.data[key] = value
    
    
        def __delitem__(self, key):
            print("__delitem__", key)
    
    
    obj = Foo()
    obj['name'] = 'alex'
    print(obj.data)
    del obj["name"]
    

    9. __new__ 和 __metaclass__

    先来看段代码, 一般我们普通方式创建类如下:

    class Foo(object):
    
        def __init__(self,name):
            self.name = name
    
    f = Foo("moo")
    
    print(type(f))    # 表示:obj对象由Foo类创建得来, f是Foo的一个实例
    # 返回:<class '__main__.Foo'>
    print(type(Foo))   # 表示:Foo类由type类创建得来,Foo是type的一个实例
    # 返回:<class 'type'>
    

    这里就引出了第2种创建类的方法,乃装逼利器,即特殊方式。其基本原理(以以上例子为列), f是Foo类创建的,是Foo的一个实例。在python中,一切皆对象。其实Foo类本身也是一个实例,是type类所创建的一个实例。 特殊方式创建类的方式如下:

    def func(self):
        print('hello, 特殊方法')
    
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    Moo = type("Moo", (object,), {'talk': func,
                                  '__init__': __init__})
    # type第一参数:类名
    # type第二参数:当前类的基类
    # type第三参数:类的成员
    
    m = Moo("alex", "22")
    m.talk()
    

    多数情况不大用到,重点是内部逻辑,以及“一切皆对象”的概念。

    类的创建过程(很难理解)

    类中有个属性__metaclass__, 表示该类是由谁来实例化创建的。

    __init__相比,__new__更像一个正真的构造器。因为__new__()必须返回一个合法的实例,这样调用__init__()时,就可以把这个实例作为self传给它。__init__()更像解释器创建一个实例后调用的第一个方法。

    10. 其他

    详见《python核心编程v2》平67-369

    类、实例和其他对象的内建函数

    1. issubclass(sub, sup)

    布尔函数判断一个类是另外一个类的子类或者孙类。 从2.2开始,sup可能是一个父类的集合的元祖。

    2. isinstance(obj1, obj2)

    布尔函数判断一个对象是否是另外一个给定类的实例,非常有用。 obj2 是给定类。

    3. *attr系列函数 hasattr(), getattr(), setattr(),delattr()

    重要,详见4.反射

    4. dir(obj=None)

    dir()作用在不通对象,内容不同

    1. 实例:显示实例变量,实例所在的类及所有它的基类中定义的方法及类属性
    2. 类:显示类以及他的所有基类的__dict__的内容。 但它不显示定义在元类metaclass 中的类属性
    3. 模块:显示模块的__dict__的内容
    4. 不带参数:显示调用者的局部变量

    5. super(type, obj=None)

    方便的找到所有的父类(不需要给出父类的名称),并调用其相关属性。 而不是一个个采用非绑定方式调用父类方法。

    6. var(obj=None)

    var()dir()类似。区别在于给定参数必须有一个__dict__属性。 如果返回不了一个key和value的形式,会出现TypeError异常。

     

  • 相关阅读:
    OpenCV程序在生产环境中运行
    C#调用C++导出(dllexport)方法
    IIS7.5 GZip配置
    wcf学习笔记--初识wcf
    Greenplum installation guide
    Cloudera 5.8.2 Installation guide
    WPF DataGrid 合并单元格
    wpf DataGrid CheckBox列全选
    WPF button 圆角制作
    WPF passwordbox 圆角制作
  • 原文地址:https://www.cnblogs.com/lg100lg100/p/8253886.html
Copyright © 2011-2022 走看看