zoukankan      html  css  js  c++  java
  • Python 定制类 特殊方法

    1、特殊方法

    定义在class中

    不需要直接调用,python的某些函数或操作符会自动的调用对应的特殊方法。

    如定义了person类,使用print p 语句打印person类的实例时,就调用了特殊方法__str__()

    此时就需要在person类中实现这个方法。

    使用特殊方法时注意:

    只需要编写用到的特殊方法

    有关联性的特殊方法都必须实现(如__getattr__,__setattr__,delattr__)

    2、python中 __str__和__repr__

    __str__()用于显示给用户,而__repr__()用于显示给开发人员。

    class Person(object):
        def __init__(self, name, gender):
            self.name = name
            self.gender = gender
        def __str__(self):
            return '(Person: %s, %s)' % (self.name, self.gender)
        __repr__ = __str__ #直接让repr和str相同

    定义了repr函数后,在调试时直接向命令行输入p即可输出person的信息,否则会输出

    <__main__.Person object at 0x0000000002E66C88>

    __str__和__repr__函数会被子类继承。

    3、python中 __cmp__

    为了对对象进行排序,可以使用函数sorted函数,前提是设置了类的__cmp__方法。

    class Student(object):
        def __init__(self, name, score):
            self.name = name
            self.score = score
        def __str__(self):
            return '(%s: %s)' % (self.name, self.score)
        __repr__ = __str__
    
        def __cmp__(self, s):
            if self.name < s.name:
                return -1
            elif self.name > s.name:
                return 1
            else:
                return 0
     
    >>> L = [Student('Tim', 99), Student('Bob', 88), Student('Alice', 77)]
    >>> print sorted(L)
    [(Alice: 77), (Bob: 88), (Tim: 99)]
     

    4、python中 __len__

    调用len()返回实例的长度.

    class Students(object):
        def __init__(self, *args):
            self.names = args
        def __len__(self):
            return len(self.names)
     
    >>> ss = Students('Bob', 'Alice', 'Tim')
    >>> print len(ss)
    3
    任务:

    斐波那契数列是由 0, 1, 1, 2, 3, 5, 8...构成。

    请编写一个Fib类,Fib(10)表示数列的前10个元素,print Fib(10) 可以打印出数列的前 10 个元素,len(Fib(10))可以正确返回数列的个数10。

    代码1:(参考代码)

    可以使用str()将整型列表转化为字符串。

    class Fib(object):
        def __init__(self, num):
            a, b, L = 0, 1, []
            for n in range(num):
                L.append(a)
                a, b = b, a + b
            self.numbers = L

        def __str__(self):
            return str(self.numbers)

        __repr__ = __str__

        def __len__(self):
            return len(self.numbers)

    f = Fib(10)
    print f
    print len(f)

    代码2:(自己写的)
    class Fib(object):
    
        def __init__(self, num):
            self.num = num
            
        def __str__(self):
            if(self.num==1):
                return "[0]"
            elif(self.num==2):
                return "[0,1]"
            else:
                fib_str = "[0,"
                fib=[0,1]
                for k in range(2,self.num+1):
                    fib_str = fib_str+ str(fib[k-1]) + ","
                    fib.append(fib[k-1]+fib[k-2])
                return fib_str[:-1]+']'
        def __len__(self):
            return self.num   
    
    f = Fib(10)
    print f
    print len(f)

    5、python中数学运算(运算符重载)

    例:有理数可以用p/q表示,其中p和q都是整数。

    调用求最大公约数的gcd函数(递归):

    欧几里得定理:若a=b*r+q,则 GCD(a,b)=GCD(b,q)

    def gcd(a,b):
        if(b==0):
            return a
        return gcd(b,a%b)
    class Rational(object):
        def __init__(self, p, q):
            self.p = p
            self.q = q
    
        def __add__(self, r):
            return Rational(self.p * r.q + self.q * r.p, self.q * r.q)
    
        def __sub__(self, r):
            return Rational(self.p*r.q-r.p*self.q,self.q*r.q)
    
        def __mul__(self, r):
            return Rational(self.p*r.p,self.q*r.q)
    
        def __div__(self, r):
            return Rational(self.p*r.q,self.q*r.p)
    
        def __str__(self):
            g = gcd(self.p,self.q)
            return '%s/%s' % (self.p/g, self.q/g)
    
        __repr__ = __str__
    
    r1 = Rational(1, 2)
    r2 = Rational(1, 4)
    print r1 + r2
    print r1 - r2
    print r1 * r2
    print r1 / r2

    6、python中类型转换

    __int__ 和 __float__方法实现类型转换,
    __str__ 方法也可以看做是一种类型转换。
    class Rational(object):
        def __init__(self, p, q):
            self.p = p
            self.q = q
    
        def __int__(self):
            return self.p // self.q
    
        def __float__(self):
            return float(self.p)/float(self.q)
    
    print float(Rational(7, 2))
    print float(Rational(1, 3))

    7、python中 @property(装饰器函改写set和get方法)

    @property 修饰方法后即是get方法。

    “@+方法名字+点+setter”是个固定格式与@property搭配使用,set方法。

    如果没有定义set方法,就不能对“属性”赋值,这时,就可以创建一个只读“属性”。

     
    class Student(object):
        def __init__(self, name, score):
            self.name = name
            self.__score = score
        @property
        def score(self):
            return self.__score
        @score.setter
        def score(self, score):
            if score < 0 or score > 100:
                raise ValueError('invalid score')
            self.__score = score

    8、python中 __slots__ 属性限制

    __slots__规定了一个类允许的属性列表。不允许添加列表外的属性。

    class Student(object):
        __slots__ = ('name', 'gender', 'score')
        def __init__(self, name, gender, score):
            self.name = name
            self.gender = gender
            self.score = score
    强行添加grade属性会报错。
    >>> s = Student('Bob', 'male', 59)
    >>> s.name = 'Tim' # OK
    >>> s.score = 99 # OK
    >>> s.grade = 'A'
    Traceback (most recent call last):
      ...
    AttributeError: 'Student' object has no attribute 'grade'

    9、python中__call__  把类实例变成可调用对象

    class Person(object):
        def __init__(self, name, gender):
            self.name = name
            self.gender = gender
    
        def __call__(self, friend):
            print 'My name is %s...' % self.name
            print 'My friend is %s...' % friend
     
    >>> p = Person('Bob', 'male')
    >>> p('Tim')
    My name is Bob...
    My friend is Tim...
     
    第四节的斐波那契数列问题,可以改用call实现。
    class Fib(object):
            
        def __call__(self,num):
            a=0
            b=1
            L=[]
       
            for n in range(1,num+1):
                L.append(a)
      
                temp = b
                
                b = a + b
                a = temp
          
            return L
                
    f = Fib()
    print f(10)
     
    参考代码:
    class Fib(object):
        def __call__(self, num):
            a, b, L = 0, 1, []
            for n in range(num):
                L.append(a)
                a, b = b, a + b
            return L
    
    f = Fib()
    print f(10)

    注意代码中 高亮语句,使用参考代码的写法,就省去了一个中间变量。

     
  • 相关阅读:
    转:gpio_direction_output 与 gpio_set_value
    转:gpio_request
    转: 静态模式makefile中$(cobjs): $(obj)/%.o: $(src)/%.c
    转:misc_register、 register_chrdev 的区别总结
    转:aptitude 命令详解
    转:Ubuntu12.04 LTS 使用心得-开机挂载其他分区
    转:大端模式和小段模式简述
    转:C++中 #ifdef 和#endif的作用
    转:FIFO和DMA
    Camera Link 信号源板卡学习资料第153篇: 基于Sprtan6的Full(Base) Camera Link 信号源
  • 原文地址:https://www.cnblogs.com/oucsheep/p/6711461.html
Copyright © 2011-2022 走看看