2013-05-11 58 views
3

我想使用python-twitter,但扩展Status类以添加一些新的方法和属性。什么是pythonic的方式来做到这一点?Python - 如何更改模块实现?

目前,我的功能是为Status添加属性和新功能,例如,

process_status(status): 
    status.datetime = ... 
    status.phrase = ... 

prettyprint_status(status): 
    # do something... 

当然,我只是想在Status构造函数中添加额外的方法。我发现了一个stackoverflow question discussing this其中提出做一个新的模块,ext-twitter,它包含每个类的新的实现,如如下:

# 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()它没有引用我的扩展状态类。

有什么方法可以将我的功能添加到python-twitter模块而不分叉它并创建自己的版本?

回答

2

试试这个:

# 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中的类对象的引用,那么这些引用将不会更新。这并不经常发生,但它可能是微妙的错误的来源。

在导入twitter.py之后以及执行其他操作之前,您需要立即导入。

+0

谢谢,这个工作,一旦我改变了构造带** kwargs以及*指定参数时,和状态(TwitterStatus)构造函数需要调用TwitterStatus而不是twitter.Status来避免循环自引用。编辑你的答案来反映这个 – dandelion 2013-05-12 19:54:27

+0

啊,好的。请注意,对超类构造函数的调用最好使用'super'执行。谷歌“Python超级认为超级”是一个很好的指南。如果你使用Py3k,它会更好。 – Marcin 2013-05-12 20:16:55

1

而不是使用继承,你可以用成分来增加功能Status对象:

# 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 
+0

我试图实现[一个简单的例子](https://gist.github.com/danmane/5564726)。当我调用SpottedDog组合构造函数时,它会导致无限递归 – dandelion 2013-05-12 20:06:38

+0

不幸的是,我从头开始写道,忘记了为__setattr__方法中的'_internal'属性添加异常。这种方法唯一的问题是你的装饰器类不能拥有他自己的属性,除非你确定了装饰器类将会拥有的属性的'白名单',并且修改'__setattr__'方法来尊重它。 – asermax 2013-05-13 00:01:17