zoukankan      html  css  js  c++  java
  • python中的interface, abstract class, class property

    1. python class的继承

    python允许多根继承, 这点像C++, 但不像C++那样变态, 需区分公有继承/私有继承/保护继承, python只有一种继承方式。也许正因为支持多重继承, 因此python没有interface这个关键词. 

    2. 给类起个别名

    在python中, class也是对象, 所以你可以像操作对象一样, 将class赋值给一个对象, 这样就相当于给class起了一个别名

    可以在代码中:

     ShortName = MyReallyBigClassNameWhichIHateToType

    或者在import时候, 

     from modulename import ReallyLongNameWhichIHateToType as FriendlyName

    3.  如何访问父类的成员

    大概有3中方法吧:

    a. 可以在子类中, 直接通过父类名来调用父类的成员,

    b. 也可以先给父类起个别名, 然后使用别名来访问父类成员. 

    c. 使用super()内建方法, 但使用super(), 有时候并不像你想象的那样, 下面的链接有更多的信息

    python中的super

    http://only-u.appspot.com/2010/04/29/python.html

    http://kanrss.com/@kevin/t/1447052

    MRO & super

    http://blog.csdn.net/seizeF/archive/2010/02/18/5310107.aspx 

    4. python有interface和abstract class吗?
    没有interface, 这个真没有!  那就用abstract class来模拟interface定义吧! 呵呵, python好像连abstract class也不是原生态的, 好在还有一个ABC(abstract base class), 将就用吧. 
    abstract base class
    http://3.1.onlypython.appspot.com/post/3521/
    下面是一个例子:
    代码
    #-----------------------
    from abc import ABCMeta, abstractmethod

    class Drawable():
    __metaclass__ = ABCMeta

    @abstractmethod
    def draw(self, x, y, scale=1.0):
    pass

    def draw_doubled(self, x, y):
    self.draw(x, y, scale
    =2.0)

    class Square(Drawable):
    def draw(self, x, y, scale): #####
    pass

    c
    =Square()
    #-----------------------
    Square类一定要实现draw()方法, 否则, 当实例化一个Square对象时, 将报错TypeError: Can't instantiate abstract class Square with abstract methods draw
    5. 那么有没有C#的property概念呢?
    可以有2种方式, 一个是使用x=property(getter,setter, deleter)的方式, 另一个是@property,@x.setter,@x.deleter
    http://blog.csdn.net/seizeF/archive/2010/05/03/5553136.aspx
    http://www.builderau.com.au/program/python/soa/Less-painful-getters-and-setters-using-properties-in-Python/0,2000064084,339283427,00.htm
    http://docs.python.org/library/functions.html#property
    代码
    #---------使用property()的例子-------------------------
    class C(object):
    y
    = 3
    z
    = 4

    def __init__(self):
    self.
    __x = 2

    def getx(self):
    return self.__x

    def setx(self, val):
    print "x is read only"

    x
    = property(getx, setx) #这不是真正的只读属性, 虽然在setx中,没有更新__x, 但你仍可对x属性赋值, 虽然复制不生效, 但也不报错
    x = property(getx) #这是真正的只读属性, 不给属性增加setter, 这是真正的只读属性, 因为一旦要给x赋值的时候, 运行就报错
    x = property(lambda self: self.__x)#这是真正的只读属性, 因为一旦要给x赋值的时候, 运行就报错

    c
    =C()
    print(c.x,c.y,c.z)
    c.x
    =3
    print(c.x,c.y,c.z)
    #----------------------------------
    代码
    #----------使用@property的例子------------------------
    class B(object):
    def __init__(self):
    self._x
    = None

    @property
    def x(self): #这是x的getter
    """I'm the 'x' property."""
    return self._x

    @x.setter
    def x(self, value): #这是x的setter
    self._x = value

    @x.deleter
    def x(self): #这是x的deleter
    del self._x

    b
    =B()
    b.x
    =12
    print(b.x)
    #----------------------------------
    6. 抽象类中, 可以包括abstract property, 和property一样, 也可以使用两种方式来定义抽象属性, 使用abstractproperty()或@abstractproperty
    代码
    #--------使用abstractproperty()------------------------------
    from abc import ABCMeta
    from abc import abstractproperty
    from abc import abstractmethod

    class IMediaPlayer_1:
    """API for accessing a media player"""
    __metaclass__ = ABCMeta

    def get_volume(self):
    pass
    def set_volume(self, value):
    pass
    volume
    = abstractproperty(get_volume, set_volume,
    doc
    ="Return or set volume: 0..100")


    class WinMediaPlay_1(IMediaPlayer_1):
    def __init__(self):
    self._volume
    =0

    def get_volume(self):
    return self._volume

    def set_volume(self, value):
    self._volume
    =value

    volume
    = property(get_volume, set_volume,
    doc
    ="Return or set volume: 0..100")


    player1
    =WinMediaPlay_1()
    player1.volume
    =10
    print(player1.volume)
    #--------------------------------------
    代码
    #-----------使用@abstractproperty---------------------------
    from abc import ABCMeta
    from abc import abstractproperty
    from abc import abstractmethod

    class IMediaPlayer_2:
    """API for accessing a media player"""
    __metaclass__ = ABCMeta

    @abstractproperty
    def price(self):
    """I'm the 'x' property."""
    pass

    @price.setter
    def price(self, value):
    pass


    class WinMediaPlay_2(IMediaPlayer_2):
    def __init__(self):
    self._price
    =0

    @property
    def price(self):
    """I'm the 'x' property."""
    return self._price

    @price.setter
    def price(self, value):
    self._price
    =value


    player2
    =WinMediaPlay_2()
    player2.price
    =20
    print(player2.price)
    #--------------------------------------

    7. python 类的 static variable 

    在类的__init__()中, 引出的变量为实例变量, 直接在类块中引出的变量为静态变量. 

    8. python 类的 static method 和 class method

    python中有static method 和 class method之分, 一般讲, 差异不大, 可以混着用. 

    @staticmethod decorator之后的方法为static方法. 

    @classmethod decorator之后的方法为类方法, 它的第一个参数必须为cls, (注:实例方法的第一个参数是self). 如果你是通过sub_class来调用base_class的一个classmethod, 那么函数体中, cls.__name__为sub_class, 而不是base_class.  正是因为这点, python的类方法比static方法更流行一些, 这尤其是在工厂类中特别有用. 

  • 相关阅读:
    C#手写日志(txt格式)
    dedecms:解析Robots.txt 协议标准
    dedecms列表页有图调用缩略图无图留空的方法
    简单的随机数实现
    单页面定时跳转的办法小结
    css3通过scale()实现放大功能、通过rotate()实现旋转功能
    rem自适应布局小结001
    Java的BIO、NIO、AIO
    Java实现静态代理、动态代理
    博弈论基础
  • 原文地址:https://www.cnblogs.com/harrychinese/p/python_interface_and_abstract_class_and_property.html
Copyright © 2011-2022 走看看