Tags : Ajax  apache  awk  besttrace  bootstrap  CDN  Django  git 

常见问题

用python做些事:类

stevezhou      2015.11.15   


基本语法

​经典类:没有明显写出父类,有可能不继承自任何对象

新式类:有显式写出父类,至少继承自object

经典类与新式类区别

1) __slots__,

2) 继承顺序,super

3) __new__,

4) __getattribute__

# python3里所有的类都是新式类

属性

类属性

实例属性

私有属性

_x :可以通过属性名正常访问,需要自己人为约束调用行为

__x :不可能直接访问,但通过'_类名__x'的方式仍可以访问

__x__:系统自带的类私有属性,可以通过属性名正常访问

装饰器描述符

@property   #把方法变成属性去访问

@属性.setter  #‘属性’要与定义的方法名相同

@属性.deleter

在set值是对属性进行检查

__getattr__ #当调用的属性找不到时,会自动调用__getattr__函数

__setattr__

__delattr__

__slots__:

并没有限制对属性的访问,因为只要你把__dict__加入到__slots__中,你仍然可能设置或删除__slots__规定以外的属性。要真正达到限制访问,可能在每对属性进行操作(设置或删除)时,对属性是否在__slots__中进行检查; 

描述符

数据描述符:实现了__get__、__set__的类,可以作为另一个类的属性

非数据描述符:仅实现了__get__

方法

类方法,@classmethod     ——绑定类

实例方法              ——绑定实例对象

静态方法,@staticmethod    ——无绑定,与函数无区别,只不过是通过类或实例进行调用

特殊方法(魔法方法),__init__ ——在某些场景下进行自动调用,可以是类方法或实例方法

#与函数的区别

形式上的区别

1、调用是通过类和实例进行的,不能直接调用

2、有自己的特殊参数,self,cls

3、有自己的声明语法,@classmethod,@staticmethod,__XX__()

#实质的区别在于绑定

示例:

#coding:utf-8

class Date(object):
    def __init__(self,day=0,month=0,year=0):
        self.day=day
        self.month=month
        self.year=year

    def __str__(self):
        return "{0}-{1}_{2}".format(self.year,self.month,self.day)

    @classmethod
    def from_string(cls,date_as_string):
        year,month,day=map(int,date_as_string.split('-'))
        date1=cls(day,month,year)
        return date1

    @staticmethod
    def is_date_valid(date_as_string):
        year,month,day=map(int,date_as_string.split('-'))
        return day <=31 and month <=12 and year <=3999

    @staticmethod
    def millenium(month,day):
        return Date(month,day,2000)

class DateTime(Date):
    def __str__(self):
        return "{0}-{1}-{2} - 00:00:00PM".format(self.year,self.month,self.day)

if __name__=="__main__":
    s='2015-11-18'
    if Date.is_date_valid(s):
        date1=Date.from_string('2015-11-18')
        print date1
        date2=DateTime.from_string('2015-11-18')
        print date2
    m1=Date.millenium(11,18)
    print m1
    m2=DateTime.millenium(11,18)
    print m2

特殊方法

属性访问:__getattr__,__setattr__,__getattribute__

实例生成/类生成:__init__,__new__

数字计算:__add__,__sub__,__mul__,__div__,__pow__,__round__

调用方法:__str__,__repr__,__len__,__bool__

比较大小:__cmp__,__lt__,__le__,__eq__,__ne__,__gt__,__ge__

# l:less , t:than , e:equal , g:great , n:negative

集合访问:__setslice__,__getslice__,__getitem__,__setitem__,__contains__

迭代器:__iter__,__next__

 

继承

实例.__class__ :查看是哪个类的实例,如a是类A的实例,则 a.__class__就显示A

实例.__class__.__base__:查看父类

多重继承

经典类(Classic):继承顺序深度优先,可用inspect库getmro()方法查看继承优先顺序

新式类(New):继承顺序广度优先 ,可用特殊方法__mro__ 查看继续优先顺序(只能用类名,不能用实例名),如 A.__mro__

 

经典类示例:

class A:
  a=1
  b=1

class B(A):
  b=2

class C(A):
  a=3
  b=3
  c=3

class D(B,C):
  pass

if __name__=='__main__':
  d=D()
  #查看d的属性值

 

新式类示例:

class A(object):
  a=1
  b=1

class B(A):
  b=2

class C(A):
  a=3
  b=3
  c=3

class D(B,C):
  pass

if __name__=='__main__':
  d=D()
  #查看d的属性值

.如何解决一个父类方法被重复调用?

解决方法:用super方法super方法仅在新式类里面有

如上例中,在调用父类方法时用:super(D,self).test()

 

组合

通过已有的类生成新类。

以已有类的实例作为参数,初始化新类的成员。

多态

多态是不同类的相同方法,相同参数,不同功能。调用时便于将一组对象放在集合里,无需判断对象的具体类型,统一调用。

重载:相同方法的不同参数类型。对应python的args,kwargs.

为什么会有多态?

面向对象的设计原则:里氏代换原则,即 父类出现的地方,子类一定可以出现,反之则不一定;

 

元类

用来创建类的类,即类是元类的实例。

需要理解python中:一切皆为对象。

__class__:用来查看是哪个类的实例。

type是python中内建的元类。

自定义元类:__metaclass__,你可以在__metaclass__中放置些什么代码呢?答案就是:可以创建一个类的东西。那么什么可以用来创建一个类呢?type,或者任何使用到type或者子类化type的东东都可以。<摘自:http://blog.jobbole.com/21351/>

 

 



标签 :  python 上一篇     下一篇