python 系列 (1)-13-装饰器 面向对象

	# 面向对象第2节
	##知识点:
	# 多继承
	# 特殊方法
	# 装饰器
	
	# 多继承
	class A:
	    def show(self):
	        print('AAAA')
	
	class B:
	    def show(self):
	        print('BBBB')
	
	class C(A,B):
	    def show(self):
	####        B.show(self)
	##        super().show()     调用父类的方法,多继承按照继承类的顺序,只调用一次
	        print('CCCCC')
	
	cc = C()
	# 如果要完全重新,就不用调用以及使用super
	# 如果要在继承的基础上增加功能。
	
	
	
	
	# 特殊方法
	#实例调用:
	'''
	__init__    初始化
	__repr__    c1
	__str__     print (c1 )(如果类里面先定义了__repr__的话print x时也会返回对应的
	__call__    c1()   使实例可被调用
	__getattr__
	'''
	class Rectangle:
	    def __init__(self,width,height):
	        self.width = width
	        self.height = height
	        
	    def __str__(self):  # print
	        return '宽为%s,高为%s'%(self.width,self.height)
	    
	    def __repr__(self):  # c1
	        return 'HHAHAHHAH'
	
	    def __call__(self):
	        return 'xixixiixi'
	
	    def area(self):
	        return self.width*self.height
	
	    def __add__(self,other):
	        return self.area()+other.area()
	
	
	
	##    def __getattr__(self,x):    # c1.yy
	##        return x
	####    def __setattr__(self,name,value):    #c1.xx='yy'
	####        print('xxixixiixixix')
	####        self.__dict__[name] = value
	####        return self.name
	
	#c1 =Rectangle(3,4)
	
	'''
	>>> c1
	HHAHAHHAH
	>>> print(c1)
	宽为3,高为4
	>>> 
	'''
	
	# 运算符魔法方法:
	'''
	__add__(self,other)     x+y
	__sub__(self,other)     x-y 
	__mul__(self,other)     x*y  
	__mod__(self,other)    x%y
	__iadd__(self,other)    x+=y
	__isub__(self,other)    x-=y 
	__radd__(self,other)    y+x
	__rsub__(self,other)     y-x 
	__imul__(self,other)    x*=y 
	__imod__(self,other)    x%=y
	'''
	
	
	# 装饰器
	
	"""
	打个比方,正常人都会穿鞋,但是呢有些人在鞋子里面就会放个增高鞋垫,这个增高鞋垫
	不影响穿鞋子,但是呢会让穿的人看上去更高一点,装饰器就像这个增高鞋垫一样,
	它不影响函数的正常使用,但是可以给函数增加更多的功能
	"""
	'''
	内置装饰器:Python写好,我们可以直接拿来用
	@ 语法糖
	@property 装饰过的函数返回的不再是一个函数,而是一个property对象
	          装饰过后的方法不再是可调用的对象,可以看做数据属性直接访问。
	@staticmethod 把没有参数的函数装饰过后变成可被实例调用的函数,
	             函数定义时是没有参数的。这里只是省略了self,里面还可以传参数
	             
	@classmethod 把装饰过的方法变成一个classmethod类对象,既能能被类调用又能被实例调用。
	 注意参数是cls代表这个类本身。而是用实例的方法只能被实例调用。
	 
	'''
	
	
	
	class Rectangle:
	    def __init__(self,width,height):
	        self.width = width
	        self.height = height
	        
	    @property
	    def area(self):
	        return self.width*self.height
	    
	    @staticmethod 
	    def fun():
	        return 'xxxxxxx'
	    
	    @classmethod
	    def show(cls):
	        print(cls)       #代表类本身cls
	        return 'yyyyy'
	        
	c1 = Rectangle(3,4)
	##>>> c1.area           @property     把方法编程属性一样的调用
	##12  
	##>>> c1.fun()           @staticmethod 静态方法 把无参数编程可实例调用的函数,这里只能在类内部
	##'xxxxxxx'
	##>>> c1.show()
	##<class '__main__.Rectangle'>   类对象本身
	##'yyyyy'
	##>>> 
	
	
	c2 = Rectangle(4,5)
	
	
	# 自定义装饰器 函数
	# 内嵌函数和闭包
	def ff1(x):
	    def ff2(y):
	        return x*y
	    return ff2
	
	def fun1(x):  # x=ff
	    def fun2(y):  # y=4
	        return x(y) + 100  # 要求你的x必须为函数
	    return fun2
	
	
	@fun1    ##ff = fun1(ff)
	def ff(x):
	    return x*x
	
	
	def filterarg(x):
	    def fit(*arg):
	        if len(arg) == 0:
	            return 0
	        for i in arg:
	            if not isinstance(i,int):
	                return 0
	        return x(*arg)
	    return fit
	
	
	@filterarg
	def sums(*arg):
	    return sum(arg)
	
	@filterarg
	def average(*arg):
	    return sum(arg)/len(arg)
	
	def summ(*arg):
	    s =0
	    for i in arg:
	        s +=i
	    return s
	
	
	
	
	
	
	# 作业:
	#1:
	# 写个名为Character的类,这个类继承了str类。
	# 把上次考试的前三题的函数封装到Character类中,作为这个类的方法。
	
	
	class Character(str):
	
	    def reversed_seq(self,x):
	        y = list(x)
	        y.reverse()
	        if isinstance(x,str):
	                return ''.join(y)
	        else:
	                return type(x)(y)
	
	    def which_or(self,x):
	        if list(x)==sorted(x):
	                return 'UP'
	        elif list(x)==sorted(x,reverse=True):
	                return 'DOWN'
	
	
	    def charc(self,x):
	        d={'a':0,'b':0,'c':0,'d':0,'e':0,'f':0,'g':0,'h':0,'i':0,'j':0,'k':0,'l':0,'m':0,'n':0,'o':0,'p':0,'q':0
	        ,'r':0,'s':0,'t':0,'u':0,'v':0,'w':0,'x':0,'y':0,'z':0,'whitespase':0,'other':0}
	        
	        for i in x.lower():
	                if i in d:
	                        d[i]+=1
	                elif i ==' ':
	                        d['whitespase']+=1
	                else:
	                        d['other']+=1
	        return d
	
	xx  =Character()
	
	
	#2
	#定义一个矩形的类:
	##有长和宽的属性
	## 有一个计算面积的方法
	## 在类里面写一个方法判断是否为正方形
	
	class Retangle:
	    def __init__(self,weight,height):
	        self.weight =weight
	        self.height =height
	
	    @property
	    def are(self):
	        return self.weight*self.height
	
	
	    def ff(self):
	        
	        if self.weight ==self.height:
	            return '是正方形'
	        else:
	            return '非正方形'
	
	      
	
	re1 = Retangle(5,8)
	
	##>>> re1.are
	##40
	##>>> re1.ff()
	##'非正方形'
	##>>> 
	
	re2 = Retangle(8,8)
	
	##>>> re2.are
	##64
	##>>> re2.ff()
	##'是正方形'
	##>>> 
	
	
	##def ff1(x):
	##    def ff2(y):
	##        return x*y
	##    return ff2
	##
	##def fun1(x):  # x=ff
	##    def fun2(y):  # y=4
	##        return x(y) + 100  # 要求你的x必须为函数
	##    return fun2
	##
	##
	##@fun1    ##ff = fun1(ff)
	##def ff(x):
	##    return x*x    
	
	
	

装饰器 @staticmethod、@classmethod、@property

(1)@staticmethod

       staticmethod用于修饰类中的方法,使其可以在不创建类实例的情况下调用方法,这样做的好处是执行效率比较高。(类比其实就是C++里面的静态方法)当然,也可以像一般的方法一样用实例调用该方法。

类中定义的普通方法(即实例方法),需要先实例化类的一个对象再调用,无法直接用类调用。而被@classmethod或@staticmethod装饰过的方法,可以不需要实例化,直接以“类名.方法名()”的方式来调用。

@property : 将函数封装为属性。需要参数self,实例对象直接调用该方法,无需()。

@classmethod :用于装饰“类方法”。需要参数cls,无需self。该类方法可以直接被调用,而无需实例化。无 self 参数,也无法访问实例化后的对象该类方法只能访问类属性,而无法访问实例属性。

@staticmethod :静态方法。无需参数cls、self。被装饰的方法会成为静态方法,无需实例化可以调用。
 


class decorator(object):

    def print_two(self):
        print('hello, two')

    @staticmethod
    def print_hello():
        print('hello world')

    def print_one(self):
        print('hello, one')

# 调用staticmethod装饰的decorator的方法
decorator.print_hello()
# decorator.print_one()     #TypeError: print_one() missing 1 required positional argument: 'self'
decorator().print_two()

import time
class Date(object):
    def __init__(self, year, month, day):
        self._year = year
        self._month = month
        self._day = day

    @classmethod      #类方法
    def today(cls):
        # 这里第一个参数是cls, 表示调用当前的类名
        todayBackup = time.localtime()
        # 返回的是一个初始化后的类
        data1 = cls(todayBackup.tm_year, todayBackup.tm_mon, todayBackup.tm_mday)
        return data1

    @property            #属性
    def printtime(self):
        return str(self._year)+'-'+str(self._month)+'-'+str(self._day)


    def printtime2(self):
        return str(self._year) + '-' + str(self._month) + '-' + str(self._day)

    @staticmethod     #静态方法
    def timeadd(a,b):
        return a+b


'''
1. 静态方法     可以使用类名调用和使用实例调用静态方法
'''
res = Date.timeadd(2,3)   #类直接调用
print(res)

res = Date('2022','5','20').timeadd(2,3)   ##先实例化类,即对象 ,通过对象进行调用
print(res)

'''
2 . classmethod  cls通常用作类方法的第一参数  
跟self有点类似( __init__里面的slef通常用作实例方法的第一参数)。即通常用self来传递当前类的实例--对象,cls传递当前类。
'''

data = Date.today()
print(data.printtime)

'''
3.property
   Python中访问对象的属性可以这么做:实例名.变量名!!@property是python的一种装饰器,是用来修饰方法的
   我们可以使用@property装饰器来创建只读属性,@property装饰器会将方法转换为相同名称的只读属性
   @property 下方的函数只能是self参数 ,不能有其他的参数,property 常和私有属性相结合使用。
'''

# 实例化
d1=Date('2022','5','20')
# 带有 @property
print(d1.printtime)
# 不带有 @property
print(d1.printtime2())

# today = Date.today()  		# 注意此处直接调用了方法,并没有初始化生成实例类Date()
# print(today.printtime)  	# 2022-9-8
# print(Date.timeadd(2,1))  	# 3

C:\Python37\python.exe F:/python项目/DataParse/teset.py
hello world
hello, two
5
5
2022-9-8
2022-5-20
2022-5-20

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值