keweel 发表于 2017-7-28 15:26:23

{:10_269:}看得不是很懂

skysky 发表于 2017-7-29 02:27:51

完全看不懂,建议把不用装饰器的code也放上来,可以有个比较

yangjian578 发表于 2017-8-5 13:16:52

黎明§末日 发表于 2017-8-7 14:15:49

hh

18813034116 发表于 2017-8-12 22:59:16

类共享的那块代码缩进有问题
然后总结一下装饰器的关键:
首先是方法共享,即把一个方法作为其他方法的附加功能
装饰器的使用与平时的方法调用不同,它需要以@+方法名 同时放在被'装饰'的方法的前面 这种形式
这样一来当被'装饰'的方法运行时,装饰方法也会运行
总的来说,要使用方法装饰器,需要形如:
#coding=utf-8
def fun_c(fun):
    '''
    #装饰器的名字随意,这里是fun_c,它需要有一个参数,用于指待调用这个装饰器的方法
   
    :param fun:
    :return:
    '''
    def call():#这个方法名字也可以随意,当约定俗成为call,这个方法包含了装饰器方法的主体代码,同时参数方法混在里面
      print 'A'
      fun()#参数方法被夹在这里,我们都知道python代码是一行一行执行的,所以会先打印A,然后执行参数方法的代码,最后打印B
      print 'B'
    return call#必须把call方法返回,不然会提示None类型对象无法被调用,我想当被调用时,实际是这样执行的,fun_c(fun)(),所以当不是一个方法作为放回之的时候,就会产生

@fun_c#装饰器要用的话就放在被装饰方法的前面
def fun_a():
    print 'C'

fun_a()#有了装饰器的方法被执行的时候实际上执行的是fun_c(fun_c)()

然后是类共享器:
#coding=utf-8
class A:
    '''
    类共享器的特性在旧式类也可以使用,现在使用的就是旧式类,装饰类需要在构造函数时将产生方法传入,同时被调用的方法必须名为
    __call__
    '''
    def __init__(self,fun):#这里传入了参数方法fun
      self.f=fun
    def __call__(self):#这个函数的名字不能随便起,不信你试试
      print 'A'
      self.f()#然后参数方法就可以在这里被调用并执行
      print 'B'

@A
def fun_a():
    print 'C'

fun_a()

装饰器的作用是,当你需要经常讲函数代码的执行'夹在'一些相同代码的时候,这些相同代码你就可以提取出来做成装饰器,这样你就不用重复写一样的代码,而且很方便~

tongtongtong 发表于 2017-8-17 11:14:02

http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html
看了很多文章,这个最易懂,讲解了装饰器的语法和用处,大家可以参考一下,不过内置装饰器和total_ordering(cls)还不太懂,慢慢来

2012277033 发表于 2017-8-26 01:05:28

看不懂,Hello.print_hello() 调用时为什么还是说Hello没有属性print_hello()

kikouousya 发表于 2017-8-26 13:54:31

看了半天没看懂 结果一百度才懂: 实际上就是说
一个修饰符就是一个函数,它将被修饰的函数做为参数,并返回修饰后的同名函数或其它可调用的东西。

kikouousya 发表于 2017-8-26 14:09:54

   def 函数1(函数):
       函数1的函数体

   @函数名1               
    def 函数2():
      函数2的函数体

    >>>函数名2()
             ↑把函数2作为参数传入函数1, 并执行函数1

kikouousya 发表于 2017-8-26 14:24:06

这是我的理解方法:
class 类1():
    def __init__(self,func):
      (构造函数的函数体)

@类1
def 函数1():
    函数体

>>>函数1()   #调用函数1
          ↑实际效果: 把函数1作为 类1.__init__( ) 的参数传入, 并执行
                         即 把 整个函数1 作为类1的构造函数的参数 来执行类1的初始化(__init__()方法)

理想小青年 发表于 2017-9-2 07:06:44

{:10_279:}{:10_279:}

Reedy 发表于 2017-9-8 17:45:15

老师最后的例子代码缩进不大好?

应该如下:
class Hello:
@classmethod
def print_hello(cls):
      print("Hello")

也还是写在类里面的。。。。不是很明白和直接在类里面写有什么区别。 难道就只是加了修饰符之后多了一个不用绑定实例就可以调用方法的功能?

八个核桃罒 发表于 2017-9-12 22:01:25

甲鱼,你这个代码的缩进不对吧,望查证修改

gin2010 发表于 2017-9-13 17:46:50

其实就是用@timeslong 下面的函数f()来替换timeslong里面的func()

HDenis 发表于 2017-9-19 19:15:32

实在对0基础不友好

简单爱你 发表于 2017-9-29 17:27:14

{:10_266:}fuc,这个当做参数表示什么意思,不能直接help(func),虽然知道这个应该是function的缩写,但是作以它作为参数感觉挺尴尬的,但是第三个例子有缩进问题

简单爱你 发表于 2017-9-29 17:31:30

感觉func表示的是一种标识,这个自动在方法开始时调用前半段并且让结束时调用后段。感觉就像是吧修饰的方法直接插入到func的位置,然后线性执行的结果

Coolsize 发表于 2017-10-5 16:53:32

看了第二遍,突然豁然开朗

苏格拉顶 发表于 2017-10-13 11:00:43

大概理解了一些,也没完全懂。但是能感觉出来这个用处很大。
下面模拟了一个场景:
def check(fn):
    admins = ["admin","sys","sysadmin"]
    def checkargs(user, argument):
      if user not in admins:
            print("用户: %s, 无权限执行[%s]操作!" % (user,argument))
      else:
            print("验证成功!")
            return fn(user, argument)
    return checkargs

@check
def test(name,args):
    print("%s 开始执行%s任务..." % (name,args))

test("admin","select")
test("小明","select")

justloong 发表于 2017-10-30 16:37:40

import time

def timeslong(func):   
    def call():
      start = time.clock()
      print("It's time starting ! ")
      func()
      print("It's time ending ! ")
      end = time.clock()
      return "It's used : %s ." % (end - start)
    return call
   

@timeslong
def f():
    y = 0
    for i in range(10):
      y = y + i + 1
      print(y)
    return y

print(f())
运行结果:

It's time starting !
1
3
6
10
15
21
28
36
45
55
It's time ending !
It's used : 0.15272174221359658 .


我的理解如下,不知对不对,分为两步:
1. f()函数作为参数,传递到timeslong(func)中
2. 在timeslong()中把call()函数返回给f(),在这一步中等于是用call()替换了f()
页: 1 2 3 4 [5] 6 7 8 9 10 11 12 13 14
查看完整版本: Python 函数修饰符(装饰器)的使用