python 学习笔记11-----类

1、简单例子

总体来讲,python的类和C++的类,思想上是一样的。只是语法会有略微的差别,所以这里主要关注语法。先上个简单例子:

class base (object):
    static_v = 100
    def __init__(self):
        self.x = 0
        self.y = 0
        self.z = 0
        print 'aaa', self.x, self.y, self.z
    def pr(self):
        print self.x, self.y, self.z

class child(base):
    def __init__(self):
        base.__init__(self)
        self.a = 1
        self.b = 1
        self.c = 1
        print 'bbb', self.x, self.y, self.z, self.a, self.b, self.c 
    def pr(self):
        print self.x, self.y, self.z, self.a, self.b, self.c

通过这里个例子,python的基本类语法应该都包括了,大部分的思想和C++很像。

不过有一点需要强调的是__init__函数,在C++中,子类的构造函数是会调用父类的构造函数,这个是自动调用的,不需要显式调用。但是在python内不是,重写了子类__init__,父类__init__就不会被调用,如果想调用,需要像例子中那样。

2、类方法和静态方法

class Test:
    @staticmethod
    def sm():
        print "static method is called..."
        
    @classmethod
    def cm(cls):
        print "class method is called...", cls.__name__
        
Test.sm()     
Test.cm()   

看起来,类方法和静态方法貌似是一样的,因为其都是专属于类的(当然,可以通过实例来调用,但是我觉得python这样搞,把类和实例完全搞混了,所以我就理解成类方法和静态方法是专属于类的),两者的最大区别就是,类方法需要传递参数cls,这样一来,类的属性在类方法是可以随意调用的。


3、会用到的一些类属性

print Test.__doc__
print Test.__bases__
print Test.__name__
print Test.__module__

4、类和实例的内建函数

issubclass(sub, sup):判断父子类关系函数

isinstance(实例, 类):判断是否是某一类实例,可以判断内建类型(int、float等)

hasattr(), getattr(),setattr(), delattr():hasattr()函数是Boolean 型的,它的目的就是为了决定一个对象是否有一个特定的属性,一般用于访问某属性前先作一下检查。getattr()和setattr()函数相应地取得和赋值给对象的属性,getattr()会在你试图读取一个不存在的属性时,引发AttributeError 异常,除非给出那个可选的默认参数。setattr()将要么加入一个新的属性,要么取代一个已存在的属性。而delattr()函数会从一个对象中删除属性。

>>> class myClass(object):
... def __init__(self):
... self.foo = 100
...
>>> myInst = myClass()
>>> hasattr(myInst, 'foo')
True
>>> getattr(myInst, 'foo')
100
>>> hasattr(myInst, 'bar') False
>>> getattr(myInst, 'bar') Traceback (most recent call last):
File "<stdin>", line 1, in ?
getattr(myInst, 'bar')
AttributeError: myClass instance has no attribute 'bar'
>>> getattr(c, 'bar', 'oops!')
'oops!'
>>> setattr(myInst, 'bar', 'my attr')
>>> dir(myInst)
['__doc__', '__module__', 'bar', 'foo']
>>> getattr(myInst, 'bar') # same as myInst.bar #等同于 myInst.bar
'my attr'
>>> delattr(myInst, 'foo')
>>> dir(myInst)
['__doc__', '__module__', 'bar']
>>> hasattr(myInst, 'foo')
False

super(type, obj):给出当前类的父类对象,如super(MyClass,self).__init__(),这样就不用显式的给出父类。

如果obj 是一个实例,isinstance(obj,type)就必须返回True,

如果obj 是一个类或类型,issubclass(obj,type)就必须返回True

vars():方法和dict类似

class Test(object):
    def __init__(self):
        self.a = 0
        self.b = 0
        
t = Test()
print dir(t)
print t.__dict__
print vars(t) 

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b']
{'a': 0, 'b': 0}
{'a': 0, 'b': 0}

总结:获取一个实例或类的属性的方法有,__dict__、vars()、dir(),前两种基本一样,而且返回的是字典,后一种返回的列表,dir要比前面两种返回的内容多一些python自动添加的属性,如果仅仅为了获取自定义的属性,用前两种就ok啦。


5、用特殊方法定制类




一个重载__str__(用于print)和加号的类

class Time60(object):
    'Time60 - track hours and minutes'

    def __init__(self, hr, min):
        'Time60 constructor - takes hours and minutes'
        self.hr = hr
        self.min = min

    def __str__(self):
        'Time60 - string representation'
        return '%d:%d' % (self.hr, self.min)

    __repr__ = __str__

    def __add__(self, other):
        'Time60 - overloading the addition operator'
        return self.__class__(self.hr + other.hr,
            self.min + other.min)

    def __iadd__(self, other):
        'Time60 - overloading in-place addition'
        self.hr += other.hr
        self.min += other.min
        return self

一个重载迭代器next的例子:

class AnyIter(object):
    def __init__(self, data, safe=False):
        self.safe = safe
        self.iter = iter(data)
    
    def __iter__(self):
        return self
    
    def next(self, howmany=1):
        retval = []
        for eachItem in range(howmany):
            try:
                retval.append(self.iter.next())
            except StopIteration:
                if self.safe:
                    break
                else:
                    raise
        return retval
    
    

a = AnyIter(range(10))
i = iter(a)
for j in range(1, 5):
    print j, ':', i.next(j)






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值