- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想创建一个 Python 类装饰器 (*),它能够无缝包装该类可能具有的所有方法类型:实例、类和静态。
这是我目前拥有的代码,对破坏代码的部分进行了注释:
def wrapItUp(method):
def wrapped(*args, **kwargs):
print "This method call was wrapped!"
return method(*args, **kwargs)
return wrapped
dundersICareAbout = ["__init__", "__str__", "__repr__"]#, "__new__"]
def doICareAboutThisOne(cls, methodName):
return (callable(getattr(cls, methodName))
and (not (methodName.startswith("__") and methodName.endswith("__"))
or methodName in dundersICareAbout))
def classDeco(cls):
myCallables = ((aname, getattr(cls, aname)) for aname in dir(cls) if doICareAboutThisOne(cls, aname))
for name, call in myCallables:
print "*** Decorating: %s.%s(...)" % (cls.__name__, name)
setattr(cls, name, wrapItUp(call))
return cls
@classDeco
class SomeClass(object):
def instanceMethod(self, p):
print "instanceMethod: p =", p
@classmethod
def classMethod(cls, p):
print "classMethod: p =", p
@staticmethod
def staticMethod(p):
print "staticMethod: p =", p
instance = SomeClass()
instance.instanceMethod(1)
#SomeClass.classMethod(2)
#instance.classMethod(2)
#SomeClass.staticMethod(3)
#instance.staticMethod(3)
我在尝试完成这项工作时遇到了两个问题:
目前,此代码会根据未注释的注释片段生成不同的 TypeError
,例如:
TypeError:未绑定(bind)方法 wrapped() 必须使用 SomeClass 实例作为第一个参数调用(取而代之的是 int 实例)
TypeError:classMethod() 正好接受 2 个参数(给定 3 个)
(*):如果你是decorating the methods directly,同样的问题就简单多了。 .
最佳答案
因为方法是函数的包装器,所以要在构造类后将装饰器应用于类的方法,您必须:
im_func
属性从方法中提取底层函数。一旦应用了 @classmethod
装饰器,就很难区分 classmethod
和常规方法;这两种方法都是 instancemethod
类型。但是,您可以检查 im_self
属性并查看它是否为 None
。如果是这样,它就是一个普通的实例方法;否则它是一个classmethod
。
静态方法是简单的函数(@staticmethod
装饰器只是阻止应用通常的方法包装器)。所以你不必为这些做任何特别的事情,它看起来像。
所以基本上你的算法看起来像这样:
types.MethodType
吗?如果是这样,它要么是类方法,要么是实例方法。
im_self
是None
,它就是一个实例方法。通过 im_func
属性提取底层函数,对其进行修饰,然后重新应用实例方法:meth = types.MethodType(func, None, cls)
im_self
不是None
,它就是一个类方法。通过 im_func
提取底层函数并对其进行修饰。现在您必须重新应用 classmethod
装饰器,但您不能这样做,因为 classmethod()
不接受类,因此无法指定它将附加到哪个类至。相反,您必须使用实例方法装饰器:meth = types.MethodType(func, cls, type)
。请注意,此处的 type
是实际的内置 type
。types.MethodType
,那么它是一个静态方法或其他非绑定(bind)的可调用对象,所以只需装饰它。这些在 Python 3 中有所改变——未绑定(bind)的方法是那里的函数,IIRC。无论如何,这可能需要在那里完全重新考虑。
关于python - 如何创建一个能够包装实例、类和静态方法的 Python 类装饰器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8185375/
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!