@符号在python中是一个特殊的修饰符,在一定地条件下可以使代码简化,保护核心代码的完整性。
1、@property
先来看下一般情况下class类函数,定义一个Student类,stu实例化对象,输出结果显示xiaoming字样。
class Student():
def __init__(self, name):
self._name = name
def sname(self):
return self._name
stu = Student('xiaoming')
print(stu.sname())
#xiaoming
增加@property之后,输出结果也显示xiaoming字样,与上面输出结果一致,但调用的时候,stu.sname后面省了一个括号@property可以使类方法转化成属性,直接通过方法名来访问方法
class Student():
def __init__(self, name):
self._name = name
@property
def sname(self):
return self._name
stu = Student('xiaoming')
print(stu.sname)
#xiaoming
如果这时你想修改sname属性,使用下面语句,你会发现报错
stu.sname='zhangsan'
Traceback (most recent call last):
File "D:/pythonstudy/data_ap/test.py", line 120, in
stu.sname='zhangsan'
AttributeError: can't set attribute
但是这时如果使用@函数名.setter,可以重新设置属性值
class Student():
def __init__(self, name):
self._name = name
@property
def sname(self):
return self._name
@sname.setter
def sname(self, value):
self._sname = value
stu = Student('xiaoming')
stu.sname='zhangsan'
print(stu.sname)
#xiaoming
2、@classmethod
@classmethod将对象方法转化成类方法,并注意类方法函数参数写法上需要加上cls作为参数,但调用的时候不用加参数。
class MyClass():
@classmethod
def thisIsClassMethod(cls,parameter):
print("this is a class method")
print(cls.__name__)
print(type(cls)) #打印类型为classobj
if __name__ == "__main__":
MyClass.thisIsClassMethod(None)
print(type(MyClass))
'''
this is a class method
MyClass
'''
3、@staticmethod
这时将对象方法转化成静态方法,可以被类直接调用
class MyClass:
@staticmethod
def thisIsStaticMethod():
print("This is static method")
if __name__ == "__main__":
MyClass.thisIsStaticMethod()
#This is static method
4、保护核心代码
func是核心代码,不能更改,但想要在该代码基础上扩展功能。这时重新定义一个两层函数,内层函数的输出是一个函数对象,并在func函数前面增加@deco进行修饰
import time
def deco(func):
def wrapper():
startTime = time.time()
func()
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs)
return wrapper
@deco
def func():
print("hello")
time.sleep(1)
print("world")
if __name__ == '__main__':
f = func
f()
'''
hello
time is 1000 ms
world
'''
如果核心代码带参数,只需要在内层函数中增加参数即可
def deco(func):
def wrapper(a,b):
startTime = time.time()
func(a,b)
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs)
return wrapper
@deco
def func(a,b):
print("hello")
time.sleep(1)
print("result is %d" % (a + b))
if __name__ == '__main__':
f = func
f(2,4)
'''
hello
result is 6
time is 1000 ms
'''
如果参数的个数不确定的情况下,使用*args,可以理解为一个数组,**kwargs可以理解为一个键值对
如果参数的个数不确定的:
def wrapper(*args, **kwargs):
startTime = time.time()
func(*args, **kwargs)
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs)
return wrapper
@deco
def func(a,b):
print("hello,here is a func for add :")
time.sleep(1)
print("result is %d" %(a+b))
@deco
def func2(a,b,c):
print("hello,here is a func for add :")
time.sleep(1)
print("result is %d" %(a+b+c))
if __name__ == '__main__':
f = func
func2(3,4,5)
f(3,4)
'''
hello,here is a func for add :
result is 12
time is 1000 ms
hello,here is a func for add :
result is 7
time is 1000 ms
'''
@用法大概总结了这些,如果还有其他用法欢迎评论与留言