Python 包装类方法
我正在尝试创建一个带有 run 方法的对象,该方法将由 _wrap_run 方法
包装。我希望能够通过简单地键入 instance.run()
来调用该方法及其包装器,并且我希望能够对该对象进行子类化,以便我可以覆盖 run ()
方法并让它仍然执行包装器。
更简单地说,我希望人们能够子类化 A 并重写 run(),但仍然可以调用 run() 方法来执行包装器函数。
我在这个机制上遇到了一些困难。有人对这种方法有什么建议吗?
class A:
def run(self):
print "Run A"
return True
def _wrap_run(self):
print "PRE"
return_value = self.run()
print "POST"
return return_value
run = property(_wrap_run)
a = A()
a.run()
"""
Should Print:
PRE
Run A
POST
"""
class B(A):
def run(self):
print "Run B"
return True
b = B()
b.run()
"""
Should Print:
PRE
Run B
POST
"""
I'm trying to create an object with a run method that will be wrapped by a _wrap_run method
. I'd like to be able to call the method and it's wrapper by simply typing instance.run()
and I'd like to be able to subclass the object so I can override the run()
method and have it still execute the wrapper.
More simply put, I want people to be able to subclass A and override run()
but still have calls to the run()
method execute the wrapper function.
I'm having some difficulty with the mechanics of this. Does anyone have any suggestions regarding this approach?
class A:
def run(self):
print "Run A"
return True
def _wrap_run(self):
print "PRE"
return_value = self.run()
print "POST"
return return_value
run = property(_wrap_run)
a = A()
a.run()
"""
Should Print:
PRE
Run A
POST
"""
class B(A):
def run(self):
print "Run B"
return True
b = B()
b.run()
"""
Should Print:
PRE
Run B
POST
"""
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用元类。
现在,如果其他人子类化
MyClass
,他们仍然会包装他们的run()
方法。Use a Metaclass.
Now if other people subclass
MyClass
, they will still get theirrun()
methods wrapped.最简单的方法:让
run
包装器,并将私有方法作为可重写的方法。Easiest way: make
run
the wrapper, and a private method be the overrideable one.其他人所做的
通常就足够了。
如果您想担心有人“破坏”这一点,请立即停止。不要浪费时间担心。
这是Python。我们这里都是成年人了。所有恶意的反社会者都会通过复制、更改然后破坏代码来破坏您的所有代码。无论你做什么,他们都会复制你的代码并修改它以破坏聪明的部分。
其他人都会阅读您的评论并遵守您的规则。如果他们想使用你的模块/包/框架,他们会合作。
What other folks do
That's usually sufficient.
If you want to worry about someone "breaking" this, stop now. Don't waste time worrying.
It's Python. We're all adults here. All the malicious sociopaths will break all you code by copying it, changing it, and then breaking it. No matter what you do, they'll just copy your code and modify it to break the clever bits.
Everyone else will read your comment and stick by your rules. If they want to use your module/package/framework, they will cooperate.
稍后,但如果该方法是普通方法,您可以使用常规装饰器。以下面的示例为例,它是一个简化的 SSH 连接器。
在此示例中,我们只希望在实例化的 SSH 对象具有
self.connected=True
时调用方法call_only_if_connected
(顾名思义)。我们可以在类外部定义一个普通的包装器,并且由于
self
或类的实例始终作为第一个参数传递(args[0]
),我们可以在那里进行检查。考虑:请注意,在上面的示例中,如果对象没有
connected
属性,将会抛出AttributeError
,因此定义connected=False< /code> 尽快(即,一旦在
__init__
中实例化该对象)。您可以按照自己的意愿处理不正确的连接;在上面的示例中,我抛出了一个
RuntimeError
。Here a while later, but if the method is a normal method, you could just use a regular decorator. Take the example below, which is a simplified SSH connector.
In this example, we only want the method
call_only_if_connected
to be called, as the name implies, if the SSH object that it is instantiated to hasself.connected=True
.We can define a normal wrapper outside the class, and since
self
, or the instance of the class, is always passed as the first arg (args[0]
), we can just make out check there. Consider:Note in the above example that an
AttributeError
will be thrown if the object does not have aconnected
property, so it is important to defineconnected=False
as soon as possible (i.e., as soon as you instantiate the object in__init__
).You could handle the improper connection how you'd like; in my example above, I am throwing a
RuntimeError
.你所拥有的基本上是一个装饰器,所以为什么不继续实现
_wrap_run
作为装饰器并在子类化函数时应用它?What you have there is basically a decorator, so why not go ahead and implement
_wrap_run
as a decorator and apply it when subclassing the function?