Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从类到装饰器的python3自变量_Python_Python 3.x_Python 3.5 - Fatal编程技术网

从类到装饰器的python3自变量

从类到装饰器的python3自变量,python,python-3.x,python-3.5,Python,Python 3.x,Python 3.5,我正在尝试构建我的第一个装饰器并在类中实现它 # decorator class class Cache(object): def __init__(self,filename,**kwargs): self.time_ago = datetime.now() - timedelta(**kwargs) self.filename = filename def __call__(self,fn): if not os.path.isfile(self.filen

我正在尝试构建我的第一个装饰器并在类中实现它

# decorator class
class Cache(object):
  def __init__(self,filename,**kwargs):
    self.time_ago = datetime.now() - timedelta(**kwargs)
    self.filename = filename

  def __call__(self,fn):
    if not os.path.isfile(self.filename):
      return self.cache(fn(self))

    time_ago = self.time_ago
    filename = self.filename
    c_age = datetime.fromtimestamp(os.path.getctime(filename))
    m_age = datetime.fromtimestamp(os.path.getmtime(filename))
    print (c_age)
    print (m_age)
    print (time_ago)
    if c_age < time_ago or m_age < time_ago:
      return self.cache(fn(self))
    else:
      return self.read()

  def cache(self,data):
      with open(self.filename,'r+') as ef:
        ef.write(data)
        return ef.read()

  def read(self):
    f = open(self.filename,'r')
    data = f.read()
    f.close()
    return data
我这样称呼它:

z = Zabb()
nodes = z.getNodes()
我得到以下错误:

Traceback (most recent call last):
File "./deco.py", line 52, in <module>
nodes = z.getNodes()
TypeError: 'str' object is not callable
回溯(最近一次呼叫最后一次):
文件“/deco.py”,第52行,在
nodes=z.getNodes()
TypeError:“str”对象不可调用

我很快就能做到这一点了。我做错了什么?

您需要从
\uuu调用\uu
方法返回一个高阶函数(包装)。添加一个内部方法并返回它

def __call__(self, fn):
    def wrapper(*args, **kwargs): # <-- Add this wrapper
        if not os.path.isfile(self.filename):
            return self.cache(fn(*args, **kwargs))

        time_ago = self.time_ago
        filename = self.filename
        c_age = datetime.fromtimestamp(os.path.getctime(filename))
        m_age = datetime.fromtimestamp(os.path.getmtime(filename))
        print (c_age)
        print (m_age)
        print (time_ago)
        if c_age < time_ago or m_age < time_ago:
            return self.cache(fn(*args, **kwargs))
        else:
            return self.read()
    return wrapper # <-- Return the wrapper
def\uuu调用(self,fn):

def wrapper(*args,**kwargs):#如果您忘记了
@deco
语法糖及其真正作用的原因,那么装饰器更容易理解。以你为例,

@Cache('nodes.json',minutes=1)
def getNodes(self):
    return "Get Nodes"
真正的意思是:

def getNodes(self):
    return "Get Nodes"

getNodes = Cache('nodes.json',minutes=1)(getNodes)
它实际上将
Zabb.getNodes
重新绑定到
缓存的结果('nodes.json',minutes=1)。\uuuu调用(getNodes)
-这是一个字符串,而不是函数

您要做的是使
缓存。\uuuu call\uuuu
返回一个函数,该函数将调用包装为修饰函数,即:

  def __call__(self,fn):
    def wrapper(*args, **kw):
      if not os.path.isfile(self.filename):
        return self.cache(fn(self))

      time_ago = self.time_ago
      filename = self.filename
      c_age = datetime.fromtimestamp(os.path.getctime(filename))
      m_age = datetime.fromtimestamp(os.path.getmtime(filename))
      print (c_age)
      print (m_age)
      print (time_ago)
      if c_age < time_ago or m_age < time_ago:
        return self.cache(fn(self))
      else:
        return self.read()
    return wrapper
def\uuu调用(self,fn):
def包装(*参数,**kw):
如果不是os.path.isfile(self.filename):
返回self.cache(fn(self))
time\u ago=self.time\u ago
filename=self.filename
c_age=datetime.fromtimestamp(os.path.getctime(文件名))
m_age=datetime.fromtimestamp(os.path.getmtime(文件名))
打印(c_年龄)
打印(m_年龄)
打印(时间\单位前)
如果c_age
\uuuuuu调用
需要返回高阶函数(已包装)
  def __call__(self,fn):
    def wrapper(*args, **kw):
      if not os.path.isfile(self.filename):
        return self.cache(fn(self))

      time_ago = self.time_ago
      filename = self.filename
      c_age = datetime.fromtimestamp(os.path.getctime(filename))
      m_age = datetime.fromtimestamp(os.path.getmtime(filename))
      print (c_age)
      print (m_age)
      print (time_ago)
      if c_age < time_ago or m_age < time_ago:
        return self.cache(fn(self))
      else:
        return self.read()
    return wrapper