- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个类装饰器,它修改了一些函数而不是其他函数。简化示例:
import functools
import inspect
import types
def mydecorator(myobj):
@functools.wraps(myobj)
def decorated_method(*args, **kwargs):
print("I'm decorated!")
return myobj(*args, **kwargs)
if inspect.isclass(myobj): # act as class decorator
for name, obj in myobj.__dict__.items():
if name == "add":
setattr(myobj, name, types.MethodType(mydecorator(obj), myobj))
return myobj # return decorated class
elif inspect.isfunction(myobj): # act as function decorator
return decorated_method
else:
assert False, "can decorate only classes and functions"
因此这将修改任何 add
方法以在它运行之前打印“I'm decorated”。
我们将把它应用到这个类:
class MyClass:
def add(self, x, y): return x + y
def mul(self, x, y): return x * y
它工作正常。我们做
#--- try out undecorated MyClass:
print("MyClass.add:", MyClass.add, "MyClass.mul:", MyClass.mul)
print("3+4 =", MyClass().add(3, 4), "3*4 =", MyClass().mul(3, 4), )
#--- decorate MyClass:
print("MyClass = mydecorator(MyClass)")
MyClass = mydecorator(MyClass)
#--- try out decorated MyClass in the same manner:
print("MyClass.add:", MyClass.add, "MyClass.mul:", MyClass.mul)
print("3+4 =", MyClass().add(3, 4), "3*4 =", MyClass().mul(3, 4), )
并获得此输出(来自 Linux 上的 CPython 3.6.7)
MyClass.add: <function MyClass.add at 0x7faededda0d0> MyClass.mul: <function MyClass.mul at 0x7faededda158>
3+4 = 7 3*4 = 12
MyClass = mydecorator(MyClass)
MyClass.add: <bound method MyClass.add of <class '__main__.MyClass'>> MyClass.mul: <function MyClass.mul at 0x7faededda158>
I'm decorated!
3+4 = 7 3*4 = 12
所以 mul
仍然是一个普通函数,而修饰的 add
变成了一个绑定(bind)方法。装饰工作正常。
但是当我现在改变方法使得 add
调用 mul
(忽略这没有多大意义的事实)如下:
class MyClass:
def add(self, x, y): z = self.mul(x, y); return x + y
def mul(self, x, y): return x * y
输出变成这样:
MyClass.add: <function MyClass.add at 0x7fbc760870d0> MyClass.mul: <function MyClass.mul at 0x7fbc76087158>
3+4 = 7 3*4 = 12
MyClass = mydecorator(MyClass)
MyClass.add: <bound method MyClass.add of <class '__main__.MyClass'>> MyClass.mul: <function MyClass.mul at 0x7fbc76087158>
I'm decorated!
Traceback (most recent call last):
File "tryout.py", line 34, in <module>
print("3+4 =", MyClass().add(3, 4), "3*4 =", MyClass().mul(3, 4), )
File "tryout.py", line 16, in decorated_method
return myobj(*args, **kwargs)
File "tryout.py", line 7, in add
def add(self, x, y): z = self.mul(x, y); return x + y # round 2
TypeError: mul() missing 1 required positional argument: 'y'
事实证明,mul
(尽管它和以前一样!)现在被调用,就好像它是一个@staticmethod
:self
未通过。
我有很多问题:
add
绑定(bind)到什么对象?@classmethod
或 @staticmethod
?types.MethodType
的真正含义是什么?最佳答案
问题是您不应该用绑定(bind)方法替换函数 add
。方法的工作方式是 function
对象有一个 __get__
方法,在实例方法的情况下,该方法返回一个绑定(bind)方法,供您在提供的参数上调用.即给定
class MyClass:
def add(self, x, y):
return x + y
def mul(self, x, y):
return x * y
o = MyClass()
o.add(3,5)
等价于 type(o).__dict__['add'].__get__(o, type(o))(3 ,5)
。
您的装饰器还应该简单地返回一个新函数,而不是一个 method
对象,并让它的 __get__
方法完成它的工作。
您的新装饰器,经过一些简化:
def mydecorator(myobj):
@functools.wraps(myobj)
def decorated_method(*args, **kwargs):
print("I'm decorated!")
return myobj(*args, **kwargs)
# Decorating a function
if inspect.isfunction(myobj):
return decorated_method
# Decorating a class
if inspect.isclass(myobj):
if "add" in myobj.__dict__:
setattr(myobj, "add", mydecorator(obj))
# Or just setattr(myobj, "add", decorated_method),
# unless you think myobj.add might be a nested class
return myobj
# Anything else is type error.
raise TypeError("can decorate only classes and functions")
解决您的一些其他问题...
How does Python internally discriminate a normal method from a @classmethod or a @staticmethod?
classmethod
和 staticmethod
对象返回的对象具有与常规 function
对象不同的 __get__
方法。
Where would I have found the documentation of all this?
Descriptor How-to Guide是一个很好的起点。它描述了描述符协议(protocol),以及属性和方法等如何使用它的示例。
关于python - 类装饰器问题,或 : How does Python discriminate methods from staticmethods?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55207543/
我有以下定义: interface Dog { bark(): void; type: 'dog'; } interface Cat { meow(): void; type: 'ca
我正在研究一些通过EF4.3使用单表继承的代码。 有一个名为“用户”的实体和另一个名为“Admin”的实体。管理员继承自用户。 用户类 public class User { public i
我定义了不同的类型: type TypeNull() = class end type MyType1 = { a:int; b:int } type MyType2 = {
根据用户的 Web 浏览器添加“特殊”但不必要的内容是否可以接受?例如,是否可以显示这个: 在我所有 IE 用户的网页顶部? 最佳答案 谁可以接受?我个人认为这是一个相当蹩脚的网站的标志——它上面有一
如果这个问题很简单,我很抱歉,但我是 C++ 的新手。我正在设计一个使用二次公式计算 2 个根的程序。但是,当我的判别式为负数时,我的程序不起作用。 #define _USE_MATH_DEFINES
在某些程序中运行 addr2line 时,我在行尾收到“鉴别器 N”注释: main at/tmp/nsievebits.c:56(鉴别器 3) 手册页没有提到它,快速的谷歌搜索似乎表明主要是源代码文
我正在使用带有 MySql 数据库的 Visual Studio 2013 Web 表单应用程序来构建 Web 表单应用程序,但我一直无法通过“成员资格和角色管理”。我对成员资格使用了数据库优先方法,
我有一个非常简单的问题,但现在似乎看不出重点。我的目的是读取 VehicleCollector 对象列表,每个对象都有一个整齐的汽车列表和另一个火车列表。车辆来自一个表,并由名为 TYPE 的列区分。
使用这些类,您将如何将“Person”的记录更改为“Employee”。 /** * @Entity * @InheritanceType("SINGLE_TABLE") * @Discrimi
我已经尝试搜索文档和代码,但我无法找到这是什么以及如何更正它。 场景: 我正在使用 Ada SPARK 向量库并且我有以下代码: package MyPackage with SPARK_Mode
鉴于这两个歧视工会,我想得到 DeclaringType从一个案例来看。 type SingleCaseUnion = | One type MultiCaseUnion = | Tw
我正在使用 EF CF 方法创建一个带有 MySQL 的网站。由于某种原因,EF 在我的 Post 表中创建了一个名为“Discriminator”的列,并包含 VARCHAR“Post”。 为什么要
我有以下 json { "status": 1, "msg": "Success", "data": { "getFeeCount": [
我有一个后端 API(实现 ApiController ),我想将其放在 APIM API 后面。 ApiController 允许我们根据传入的查询参数区分两个不同的 GET 操作。当我尝试在 AP
我正在尝试创建一个新的 Set 类型: type MySet = | List of list | Sequence of seq
Mongo 文档 http://mongodb.github.io/mongo-java-driver/3.11/bson/pojos/状态: The easiest way to enable a
我正在尝试使用 swagger-codegen 为模式规范生成 Java API 客户端。该架构使用供应商扩展x-discriminator-value来创建继承模型。 例如,我使用了我发现的模式规范
(我需要一位 Python 3 内部专家) 我有一个类装饰器,它修改了一些函数而不是其他函数。简化示例: import functools import inspect import types de
使用嵌套集合查看我的对象不会抛出错误,但在尝试保存实体时出现错误 [IndexOutOfRangeException: Invalid index 15 for SqlParameterCol
在我的项目中我有: public class BaseEntity { [Key] public int Id {get; set; } } 然后我必须定义 10 多个 POCO 类来
我是一名优秀的程序员,十分优秀!