Reputation: 1782
I want to use python-twitter
, but extend the Status
class to add a few new methods and attributes. What's the pythonic way to do this?
At the moment, I have functions which add attributes and new functionality to a Status
, e.g.
process_status(status):
status.datetime = ...
status.phrase = ...
prettyprint_status(status):
# do something...
Naturally, I'd just like to add the extra methods to the Status
constructor. I found a stackoverflow question discussing this which proposed making a new module, ext-twitter
, which contains new implementations of each class, like follows:
# 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
However, this doesn't work since the Status
classes are generated by the Twitter API object, and here ext-twitter.Api()
calls python-twitter.Api()
which has no reference to my extended Status class.
Any way to add my functionality to the python-twitter module without forking it and making my own version?
Upvotes: 3
Views: 513
Reputation: 3123
Instead of using inheritance, you can use composition to add functionality to the Status
object:
# 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
Upvotes: 1
Reputation: 49816
Try this:
# 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
This should work, at least for some values of "work". If there's anything else that captures a reference to the class object originally stored in twitter.Status
, then those references won't be updated. That doesn't happen too often, but it could be a source of subtle bugs.
You'll need to import this immediately after importing twitter.py
and before doing anything else.
Upvotes: 2