zoukankan      html  css  js  c++  java
  • python_day8

    一:魔法方法

    1.__str__()

    >>> class A():
        def __str__(self):
            return "小甲鱼是帅哥"
    
        
    >>> a=A()
    >>> print(a)
    小甲鱼是帅哥
    View Code

    2.__repr__()

    >>> class B():
        def __repr__(self):
            return "小甲鱼是帅哥"
    
        
    >>> b=B()
    >>> b
    小甲鱼是帅哥
    View Code

    3.简单定制:
    基本要求:

    定制一个计时器类
    start和stop方法代表启动计时和停止计时
    假设计时器对象t1,print(t1)和直接调用t1均显示结果
    当计时器未启动或已经停止计时,调用stop方法会给予温馨提示
    两个计时器对象可以进行相加:t1+t2
    只能使用提供有限资源完成

    import time as t
    
    class MyTime():
        def __init__(self):   #进行变量和函数的初始化
            self.unit=['','','','','','']  #时间单位
            self.prompt='未开始计时' #提示语句
            self.lasted=[]  #持续时间存储的列表
            self.begin=0    #开始时间初始化
            self.end=0  #结束时间初始化
        def __str__(self):  #调用实例直接显示结果
            return self.prompt
        def __repr__(self):
            return self.prompt
        def __add__(self, other):
            prompt='总共运行了'
            result=[]
            for index in range(6):
                result.append(self.lasted[index]+other.lasted[index])
                if result[index]:
                    prompt+=(str(result[index])+self.unit[index])
            return  prompt
    
        #开始计时
        def start(self):
            self.begin=t.localtime()
            self.prompt='提示:请先调用stop停止计时'
            print('计时开始..')
    
        #内部方法,计算运行时间
        def _calc(self):
            self.lasted=[]
            self.prompt='总共运行了'
            for index in range(6):#只要前六位返回的结果
                self.lasted.append(self.end[index]-self.begin[index])
                if self.lasted[index]:
                    self.prompt+=(str(self.lasted[index])+self.unit[index])
            self.begin=0
            self.end=0
            print(self.prompt)
        #停止计时
        def stop(self):
            if not self.begin:
                print('提示:请先调用start()进行计时')
            else:
                self.end=t.localtime()
                self._calc()
                print('计时结束!')
    
    t1=MyTime()
    t2=MyTime()
    t1.start()
    t.sleep(45)
    t1.stop()
    t2.start()
    t.sleep(15)
    t2.stop()
    print(t1+t2)
    View Code


    使用time模块的localtime方法获取时间。time.localtime返回struct_time的时间格式:
    包括:tm_year 年
    月 tm_mon
    日 tm_mday
    时 tm_hour
    分 tm_min
    秒tm_sec
    weekday:0-6 0表示周日 tm_wday
    一年中的第几天1-366  tm_yday
    是否是夏令时    tm_isdst

    4.属性访问

    用__getattr__()魔法方法

    >>> c=C()
    >>> c.x
    'X_man'
    >>> getattr(c,'x','没有这个属性')
    'X_man'
    >>> getattr(c,'y','没有这个属性')
    '没有这个属性'
    View Code

    用property

    >>> class C:
        def __init_(self,size=10):
            self.size=size
        def getSize(self):
            return self.size
        def setSize(self,value):
            self.size=value
        def delSize(self):
            del self.size
        x=property(getSize,setSize,delSize)
    
        
    >>> c=C()
    >>> c.x=1
    >>> c.x
    1
    >>> del c.x
    >>> c.size
    Traceback (most recent call last):
      File "<pyshell#42>", line 1, in <module>
        c.size
    AttributeError: 'C' object has no attribute 'size'
    View Code

    5.几个魔法方法:
    __getattr__(self,name)
    定义当用户试图获取一个不存在的属性时的行为
    __getattribute__(self,name)
    定义当该类的属性被访问时的行为
    __setattr__(self,name,value)
    定义当一个属性被设置时的行为
    __delattr__(self,name)
    定义当一个属性被删除时的行为

    >>> class C:
        def __getattribute__(self,name):
            print('getttribute')
            return super().__getattribute__(name)
        def __getattr__(self,name):
            print('getattr')
        def __setattr__(self,name,value):
            print('setattr')
            super().__setattr__(name,value)
        def __delattr__(self,name):
            print('delattr')
            super().__delattr__(name)
    
            
    >>> c=C()
    >>> c.x
    getttribute
    getattr
    >>> c.x=1
    setattr
    >>> c.x
    getttribute
    1
    >>> del c.x
    delattr 
    View Code

    练习:
    写一个矩形类,默认有宽和高两个属性。如果为一个叫square的属性赋值,那么说明这是一个正方形,值就是正方形的边长,此时宽和高都等于边长。

    >>> class Rectangle:
        def __init__(self,width=0,height=0):
            self.width=width
            self.height=height  #当这两个属性被定义时,调用__setattr__()
        def __setattr__(self,name,value):#重写魔法方法
            if name=='square':
                self.width=value
                self.height=value
            else:
                super().__setattr__(name,value) #调用基类的__setattr__方法
        def getArea(self):
            return self.width*self.height
    
        
    >>> r=Rectangle()
    >>> r1=Rectangle(4,5)
    >>> r1.getArea()
    20
    >>> r1.square=10
    >>> r1.height
    10
    >>> r1.width
    10
    >>> r1.getArea()
    100
    View Code

    二:描述符

    描述符(Property的原理):描述符就是将某种特殊类型的类(含有以下三个魔方的一个或多个)的实例指派给另一个类的属性。
    __get__(self,instance,owner)
    用于访问属性,它返回属性的值
    __set__(self,instance,value)
    将在属性分配操作中调用,不返回任何内容
    __delete__(self,inatance)
    控制删除操作,不返回任何内容

    >>> class MyDecriptor:
        def __get__(self,instance,owner):
            print('getting...',self,instance,owner)
        def __set__(self,instance,value):
            print('setting',self,instance,value)
        def __delete__(self,instance):
            print('deleting',self,instance)
    
            
    >>> class Test:
        x=MyDecriptor()
    
        
    >>> test=Test()
    >>> test.x
    getting... <__main__.MyDecriptor object at 0x00357C50> <__main__.Test object at 0x00357FB0> <class '__main__.Test'>
    >>> test
    <__main__.Test object at 0x00357FB0>
    >>> Test
    <class '__main__.Test'>
    >>> test.x='X_man'
    setting <__main__.MyDecriptor object at 0x00357C50> <__main__.Test object at 0x00357FB0> X_man
    >>> del test.x
    deleting <__main__.MyDecriptor object at 0x00357C50> <__main__.Test object at 0x00357FB0>
    View Code

    ① self: MyDecriptor的实例对象,其实就是Test的属性x
    ② instance: Test的实例对象,其实就是test
    ③ owner: 即谁拥有这些东西,当然是 Test 这个类,它是最高统治者,其他的一些都是包含在它的内部或者由它生出来的
    可以利用这个重写Property
    2.练习:

    先定义一个温度类,然后定义两个描述符用于描述摄氏度和华氏度两个属性。要求两个属性会自动进行转换,也就是说你可以给摄氏度这个属性赋值,然后打印的华氏度属性是自动转换后的结果。

    >>> class Celsius:
        def __init__(self,value=26.0):
            self.value=float(value)
        def __get__(self,instance,owner):
            return self.value
        def __set__(self,instance,value):
            self.value=float(value)
    
        
    >>> class Fahrenheit:
        def __get_(self,instance,owner):
            return instance.cel*1.8+32
        def __set__(self,instance,value):
            instance.cel=(float(value)-32)/1.8
    
            
    >>> class Temperature:
        cel=Celsius()
        fah=Fahrenheit()
    
        
    >>> temp=Temperature()
    >>> temp.cle
    Traceback (most recent call last):
      File "<pyshell#125>", line 1, in <module>
        temp.cle
    AttributeError: 'Temperature' object has no attribute 'cle'
    >>> temp.cel
    26.0
    >>> temp.fah=100
    >>> temp.cel
    37.77777777777778
    View Code

    三:练习

    定制序列:
     编写一个不可改变的自定义列表,要求记录列表中每个元素被访问的次数

    >>> class CountList:
        def __init__(self,*args):
            self.values=[x for x in args]
            self.count={}.fromkeys(range(len(self.values)),0)
        def __len__(self):
            return len(self.value)
        def __getitem__(self,key):
            self.count[key]+=1
            return self.values[key]
    
        
    >>> c1=CountList(1,3,5,7,9)
    >>> c2=CountList(2,4,6,8,10)
    >>> c1[1]
    3
    >>> c2[1]
    4
    >>> c1[1]+c2[1]
    7
    >>> c1.count
    {0: 0, 1: 2, 2: 0, 3: 0, 4: 0}
    View Code

     四:迭代器
    两个BIF:iter()    next()

    >>> string='fishc'
    >>> it=iter(string)
    >>> next(it)
    'f'
    >>> next(it)
    'i'
    >>> next(it)
    's'
    >>> next(it)
    'h'
    >>> next(it)
    'c'
    >>> next(it)
    Traceback (most recent call last):
      File "<pyshell#160>", line 1, in <module>
        next(it)
    StopIteration
    View Code
    >>> string='fishc'
    >>> it=iter(string)
    >>> while True:
        try:
            each=next(it)
        except StopIteration:
            break
        print(each)
    
        
    f
    i
    s
    h
    c
    View Code

    魔法方法:__iter__()       __next__()

    >>> class Fibs:
        def __init__(self):
            self.a=0
            self.b=1
        def __iter__(self):
            return self
        def __next__(self):
            self.a,self.b=self.b,self.a+self.b
            return self.a
    
        
    >>> fibs=Fibs()
    >>> for each in fibs:
        if each<30:
            print(each)
        else:
            break
    
        
    1
    1
    2
    3
    5
    8
    13
    21
    View Code

    五:生成器

    生成器:生成器就像一个特殊的迭代器

    >>> def myGen():
        print('生成器被执行')
        yield(1)
        yield(2)
    
        
    >>> myG=myGen()
    >>> next(myG)
    生成器被执行
    1
    >>> next(myG)
    2
    >>> next(myG)
    Traceback (most recent call last):
      File "<pyshell#203>", line 1, in <module>
        next(myG)
    StopIteration
    View Code

    生成器,斐波拉契数列

    >>> def libs():
        a=0
        b=1
        while True:
            a,b=b,a+b
            yield a
    
            
    >>> for each in libs():
        if each >100:
            break
        print(each,end=' ')
    
        
    1 1 2 3 5 8 13 21 34 55 89 
    View Code


     



  • 相关阅读:
    js类型自动转换以及==对比规则
    js改变作用域链
    cookie简单实例
    js操作cookie
    body设置margin为0
    inline-block和block元素水平居中显示
    执行git clone遇到警告解决办法
    git中各大写字母表示含义
    git命令报错
    linux.txt
  • 原文地址:https://www.cnblogs.com/wwq1204/p/10715493.html
Copyright © 2011-2022 走看看