Reputation: 988
I am working on creating a python module for getting stocks data.
I have a dictionary:
{'StockSymbol': 'AMD', 'LastTradeTime': '4:00PM EST', 'ChangePercent': '+0.58', 'ID': '327', 'LastTradeDateTimeLong': 'Mar 10, 4:00PM EST', 'Index': 'NASDAQ', 'LastTradeWithCurrency': '13.91', 'LastTradeDateTime': '2017-03-10T16:00:02Z', 'LastTradePrice': '13.91', 'LastTradeSize': '0', 'PreviousClosePrice': '13.33'}
Currently I have 11 methods such as:
class Stock(object):
def getSymbol():
return self.data['StockSymbol']
def getLastTradeTime():
return self.data['LastTradeTime']
........
I use it as:
google = Stock('GOOG')
print(google.getLastTradeTime()) //4:00PM EST
My question is, Is it possible to generate these methods dynamically?
So I could do google.getLastTradeSize()
etc without defining them.
Here is a Python fiddle: https://repl.it/GSG1
Upvotes: 0
Views: 184
Reputation: 2255
In Python there's a design pattern called bunch, it works like this, I believe it can solve your problem:
class Bunch(dict):
def __init__(self, *args, **kwargs):
super(Bunch, self).__init__(*args, **kwargs)
self.__dict__ = self
def __getattribute__(self, item):
try:
return object.__getattribute__(self, item)
except:
return None
my_dict = {'StockSymbol': 'AMD', 'LastTradeTime': '4:00PM EST', 'ChangePercent': '+0.58', 'ID': '327',
'LastTradeDateTimeLong': 'Mar 10, 4:00PM EST', 'Index': 'NASDAQ', 'LastTradeWithCurrency': '13.91',
'LastTradeDateTime': '2017-03-10T16:00:02Z', 'LastTradePrice': '13.91', 'LastTradeSize': '0',
'PreviousClosePrice': '13.33'}
obj = Bunch(**my_dict)
print obj.StockSymbol
print obj.LastTradeTime
print obj.key_not_exist
And we get:
AMD
4:00PM EST
None
So you don't have to define your so-called gettter method, like what you do in Java/C++;
PS: in a real project, you can also inherit from this Bunch class.
===== Another optional ======
you can use pythonic-toolbox, a 3rd party lib maintained by me, that contains many useful tools, demos.
For your case, I think DictObj is a good choicehere in this lib.
my_dict = {'StockSymbol': 'AMD', 'LastTradeTime': '4:00PM EST', 'ChangePercent': '+0.58', 'ID': '327',
'LastTradeDateTimeLong': 'Mar 10, 4:00PM EST', 'Index': 'NASDAQ', 'LastTradeWithCurrency': '13.91',
'LastTradeDateTime': '2017-03-10T16:00:02Z', 'LastTradePrice': '13.91', 'LastTradeSize': '0',
'PreviousClosePrice': '13.33'}
from pythonic_toolbox.utils.dict_utils import DictObj
obj = DictObj(my_dict)
assert hasattr(obj, 'StockSymbol')
assert obj.StockSymbol == 'AMD'
assert 'StockSymbol' in obj
assert obj.pop('LastTradePrice') == '13.91'
assert 'LastTradePrice' not in obj # 'LastTradePrice' is popped up, so obj don't have attribute LastTradePrice anymore
del obj.LastTradeSize
assert not hasattr(obj, 'LastTradeSize') # besides pop key as a dict, you can also delete it like an attribute
obj.greetings = 'hello world' # assign new key/attribute
assert obj['greetings'] == 'hello world'
If you don't want others to change your DictObj attributes(modify, del, add), you can also use FinalDictObj, by from pythonic_toolbox.utils.dict_utils import FinalDictObj
Upvotes: 3