# 面向对象第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