Python-如何更改模块实现?
我想使用Python-如何更改模块实现?,python,oop,inheritance,module,Python,Oop,Inheritance,Module,我想使用pythontwitter,但是扩展Status类来添加一些新的方法和属性。蟒蛇式的方法是什么 目前,我有一些功能可以为状态添加属性和新功能,例如 process_status(status): status.datetime = ... status.phrase = ... prettyprint_status(status): # do something... 当然,我只想将额外的方法添加到Status构造函数中。我发现了一个建议创建一个新模块,ext
pythontwitter
,但是扩展Status
类来添加一些新的方法和属性。蟒蛇式的方法是什么
目前,我有一些功能可以为状态添加属性和新功能,例如
process_status(status):
status.datetime = ...
status.phrase = ...
prettyprint_status(status):
# do something...
当然,我只想将额外的方法添加到Status
构造函数中。我发现了一个建议创建一个新模块,exttwitter
,其中包含每个类的新实现,如下所示:
# ext_twitter.py
import twitter
class Api(twitter.Api):
pass
class Status(twitter.Status):
def __init__(self, *args):
twitter.Status.__init__(self, *args)
self.args = args
self.time = parseTime(self.created_at)
self.phrase = ...
def prettyprint(self):
# something
但是,这不起作用,因为Status
类是由Twitter API对象生成的,这里ext Twitter.API()
调用python Twitter.API()
,它没有引用我的扩展Status类
有什么方法可以将我的功能添加到PythonTwitter模块中,而不用分叉并生成自己的版本 试试这个:
# patch_twitter.py
import twitter
TwitterStatus = twitter.Status
class Status(TwitterStatus):
def __init__(self, *args, **kwargs):
TwitterStatus.__init__(self, *args, **kwargs)
self.args = args
self.time = parseTime(self.created_at)
self.phrase = ...
def prettyprint(self):
# something
twitter.Status = Status
# use api
至少对于“工作”的某些价值观来说,这应该是可行的。如果有任何其他内容捕获了对最初存储在twitter.Status
中的类对象的引用,那么这些引用将不会被更新。这种情况并不经常发生,但可能是一些微妙的bug的来源
您需要在导入twitter.py
后立即导入此文件,然后再执行任何其他操作。您可以使用composition向状态对象添加功能,而不是使用继承:
谢谢,一旦我将构造函数改为使用**kwargs和*args,这就行了,状态(TwitterStatus)构造函数需要调用TwitterStatus而不是twitter.Status,以避免循环自引用。编辑你的答案来反映这一点啊,很好。请注意,对超类构造函数的调用最好使用super
执行。谷歌“PythonSuper被认为是超级”的一个很好的指南。如果你用的是Py3k,那就更好了。我试着实现了。当我调用SpottedDog composition构造函数时,它会导致一个无限递归。很抱歉,我是从头开始写的,忘了在\uuu setattr\uuu
方法上为\u internal
属性添加异常。这种方法唯一的问题是,你的decorator类不能拥有自己的属性,除非你为你的decorator类将拥有的属性确定一个“白名单”,并修改\uuuuuu setattr\uuuu
方法以尊重它。
# ext_twitter.py
import twitter
class Api(twitter.Api):
def method_that_returns_status(self, *args, **kwargs):
status = super(Api, self).methot_that_returns_status(*args, **kwargs)
# wrap the original status with your custom status
return Status(status)
class Status(object):
def __init__(self, status):
self._internal = status
def __getattr__(self, attr):
return getattr(self._internal, attr)
def __setattr__(self, attr, value):
if attr == '_internal':
super(Status, self).__setattr__(attr, value)
else:
setattr(self._internal, attr, value)
def prettyprint(self):
# something