函数修饰符

Python函数修饰符:”@”。通过decorator装饰器模式,使得代码更简单。

1)函数必须先定义再修饰

2)修饰符”@”后面必须是之前定义的某一个函数

3)每个函数只能有一个修饰符

 

常规修饰符

除去某些特定字符串以外的修饰符,都算作普通修饰符。

经过函数修饰符修饰的函数,在被调用时会调用修饰它的函数。

def test(f):
print "before ..."
    f()
print "after ..."
 
@test
def func():
print "func was called"
 
# 输出如下
# before ...
# func was called
# after ...
# 尽管没有函数被调用,但因为执行了"@test",所以执行顺序应是:
# 1)在编译func之前,执行@test,则会函数test并将func(函数对象)作为参数传入
# 2)在test中调用f()即调用func()
 
def test(func):
    func()
print "call test"
 
def test1(f):
    f()
print "call test1"
    
def main():
@test
def fun():
print "call fun"
@test1
def fun1():
print "call fun1"
main()
 
# 输出如下
# call fun
# call fun1
# call test1
# call test

 

@classmethod

用classmethod修饰表示这是一个类方法,无需传入对象参数,但仍需用对象实例调用。如果没有用@classmethod修饰,则表示这是一个对象方法,使用时必须与一个对象绑定。

# 没有修饰,是对象方法
class MyClass():
def thisIsClassMethod(self):
print "this is a class method"
 
if __name__ == "__main__":
    c = MyClass()
    MyClass.thisIsClassMethod(c) #调用时传入参数c,否则编译错误
 
# 有修饰则表示该函数为类方法
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)

 

@property修饰符

@property:把一个实例方法转为一个(getter)只读实例属性,使得函数可像实例属性一样被’.’访问。使用property修饰的函数效率与原函数几乎一致,property略微快于原函数。

@property只是声明了被修饰函数的getter方法,仅支持’.’访问。
setter方法必须在使用了@property转化为属性后才可以声明setter方法。
setter是将已经有@property转为实例属性后,为其添加写方法。
class Student(object):
 
#将score函数转为属性,可用'.'直接访问,无需()。当然property只是声明score的getter方法
@property
def score(self):
return self._score
 
#将score函数转为属性赋值,可用'='访问。相当于setter方法
@score.setter
def score(self, value):
self._score = value
 
p = Student()
# 如果没有@property修饰,则p.score()调用
# 如果没有没有property修饰score,则不能定义它的setter方法。
p.score = 100
print p.score

 

@staticmethod修饰符

被staticmethod修饰符的表示这是一个类的静态方法,可以被类直接调用,与@classmethod的区别在于classmethod对应的方法的第一个参数为cls,为类的类型,而staticmethod不是。

 

# 将函数转为类静态方法,被类调用而不是被对象调用
class MyClass:
@staticmethod
def thisIsStaticMethod():
print "This is static method"
 
if __name__ == "__main__":
    MyClass.thisIsStaticMethod()