学习python的日常5

形如__xxx__的变量或者函数名,在python中是有特殊用途的,例如__slots__是为了绑定属性的名称,

__len()__方法是为了让class作用于len()函数,很多这样的函数都可以帮忙定制类。

定制类:   __str__:帮助返回一个字符串,可以自己设计。__repr__:前面str是返回用户看的结果,

后面这个是返回程序开发者看到的字符串,偷懒处理就可以将str方法赋给repr。

__iter__():   实现该方法可以返回一个迭代对象,然后python的for循环就会不断调用该迭代对象的

__next__()方法拿到循环的下一个值,直到遇见StopIteration错误退出循环。

__getitem__():    although Fib can use to for..in,but it seems like a list,actually it can't use like a list,

such as get the fifth element.wish it act like list get the element by index,we should use __getitem__():

class Fib(object):
    def __getitem__(self, n):
        a, b = 1, 1
        for x in range(n):
            a, b = b, a + b
        return a

  by this way,we can get what want by index:

>>> f = Fib()
>>> f[0]
1
>>> f[1]
1
>>> f[2]
2
>>> f[3]
3
>>> f[10]
89
>>> f[100]
573147844013817084101

 but list have a magic method:slice,and our Fib() get back a error,the reason is __getitem__() might give 

a int,or a slice ,so there should have a judgement:

class Fib(object):
    def __getitem__(self, n):
        if isinstance(n, int): # n是索引
            a, b = 1, 1
            for x in range(n):
                a, b = b, a + b
            return a
        if isinstance(n, slice): # n是切片
            start = n.start
            stop = n.stop
            if start is None:
                start = 0
            a, b = 1, 1
            L = []
            for x in range(stop):
                if x >= start:
                    L.append(a)
                a, b = b, a + b
            return L

now we get the function called slice.but there still have so much problems can't be achieve.

__getattr__():    normally,when call a method or attribute of a class, if it doesn't exist, it will

be reported wrong.系统会提示我们要找到这个方法或这属性才行,但python()有一个__getattr__()

方法,动态返回一个属性:

class Student(object):

    def __init__(self):
        self.name = 'Michael'

    def __getattr__(self, attr):
        if attr=='score':
            return 99



>>> s = Student()
>>> s.name
'Michael'
>>> s.score
99

一个对象实例可以有自己的属性和方法,当我们调用实例方法时,我们用instance.method()来调用。能不能直接在实例本身上调用呢?在Python中,答案是肯定的。

任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用。请看示例:

class Student(object):
    def __init__(self, name):
        self.name = name

    def __call__(self):
        print('My name is %s.' % self.name)


>>> s = Student('Michael')
>>> s() # self参数不要传入
My name is Michael.

那么,怎么判断一个变量是对象还是函数呢?其实,更多的时候,我们需要判断一个对象是否能被调用,能被调用的对象就是一个Callable对象,比如函数和我们上面定义的带有__call__()的类实例:

>>> callable(Student())
True
>>> callable(max)
True
>>> callable([1, 2, 3])
False
>>> callable(None)
False
>>> callable('str')
False

 使用枚举类:    导入enum的Enum可以把一组相关常量定义在一个class,且class不可变,而且成员可以直接比较:

from enum import Enum

Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))


from enum import Enum, unique

@unique
class Weekday(Enum):
    Sun = 0 # Sun的value被设定为0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6

  

 

  

posted @ 2017-12-04 08:59  zzy0306  阅读(191)  评论(2编辑  收藏  举报