{"id":3732,"date":"2016-02-27T05:53:08","date_gmt":"2016-02-27T10:53:08","guid":{"rendered":"http:\/\/kodegeek.com\/blog\/?p=3732"},"modified":"2016-02-28T18:34:18","modified_gmt":"2016-02-28T23:34:18","slug":"grabando-y-recuperando-datos-en-python-usando-pickle","status":"publish","type":"post","link":"http:\/\/kodegeek.com\/blog\/2016\/02\/27\/grabando-y-recuperando-datos-en-python-usando-pickle\/","title":{"rendered":"Guardando y recuperando datos en Python usando Pickle"},"content":{"rendered":"<p>Muy f\u00e1cil de usar. Aqu\u00ed les muestro como grabar un objeto (Account) el cual tiene otros objetos adentro (lista de objetos tipo &#8216;Transaction&#8217;).<\/p>\n<pre lang=\"python\">\r\n#!\/usr\/bin\/env python3\r\n# @author Jose Vicente Nunez - josevnz@kodeek.com\r\nimport os, os.path, pickle, tempfile\r\n\r\nclass Transaction:\r\n    \r\n    def __init__(self, amount, date, currency=\"USD\", conv_rate=1.0, description=None):\r\n        self.__amount = amount\r\n        self.__date = date\r\n        self.__currency = currency\r\n        if conv_rate < 0:\r\n            raise ValueError(\"Invalid amount:{0}\".format(conv_rate))\r\n        self.__conv_rate = float(conv_rate)\r\n        self.__description  = description\r\n    \r\n    @property\r\n    def amount(self):\r\n        return self.__amount\r\n    \r\n    @property\r\n    def date(self):\r\n        return self.__date\r\n\r\n    @property\r\n    def currency(self):\r\n        return self.__currency\r\n    \r\n    @property\r\n    def description(self):\r\n        return self.__description\r\n    \r\n    @property\r\n    def conv_rate(self):\r\n        return self.__conv_rate\r\n    \r\n    @property\r\n    def usd(self):\r\n        return self.__conv_rate * self.__amount\r\n    \r\nclass Account:\r\n    \r\n    def __init__(self, number, name, transactions = []):\r\n        self.__number = number\r\n        self.__name = name\r\n        if transactions == None:\r\n            self.__transactions = []\r\n        else:\r\n            self.__transactions = transactions\r\n    \r\n    @property\r\n    def number(self):\r\n        return self.__number\r\n    \r\n    @property\r\n    def name(self, name):\r\n        if name == None:\r\n            return self.__name\r\n        if len(name) < 6:\r\n            raise ValueError(\"Account name too short!\")\r\n        self.__name = name\r\n\r\n    def __len__(self):\r\n        return len(self.__transactions)\r\n    \r\n    @property\r\n    def name(self):\r\n        return self.__name\r\n        \r\n    @property\r\n    def balance(self):\r\n        balance = 0\r\n        for bal in self.__transactions:\r\n            balance += bal.usd\r\n        return balance\r\n    \r\n    @property\r\n    def all_usd(self):\r\n        return len([t for t in self.__transactions if t.currency == \"USD\"]) == len(self.__transactions)\r\n\r\n    def apply(self, transaction):\r\n        if not isinstance(transaction, Transaction):\r\n            raise ValueError(\"Invalid argument, can only add transactions!\")\r\n        self.__transactions.append(transaction)\r\n\r\n    def __getFilename(self):\r\n        return os.path.join(tempfile.gettempdir(), str(self.number))\r\n\r\n    def save(self):\r\n        fn = self.__getFilename()\r\n        fh = None\r\n        try:\r\n            fh = open(fn, 'wb')\r\n            pickle.dump([self.__name, self.__number, self.__transactions], fh, pickle.HIGHEST_PROTOCOL)\r\n        except (EnvironmentError, pickle.PicklingError) as Error:\r\n            raise SaveError(str(err))\r\n        finally:\r\n            if fh is not None:\r\n                fh.close()\r\n\r\n    def load(self):\r\n        fn = self.__getFilename()\r\n        fh = None\r\n        try:\r\n            fh = open(fn, 'rb')\r\n            (self.__name, self.__number, self.__transactions) = pickle.load(fh)\r\n        except (EnvironmentError, pickle.UnpicklingError) as Error:\r\n            raise LoadError(str(err))\r\n        finally:\r\n            if fh is not None:\r\n                fh.close()\r\n    \r\nif __name__ == \"__main__\":\r\n    transactions = []\r\n    transactions.append(\r\n                        Transaction(\r\n                                    15.0, \r\n                                    \"06-06-1966\", \r\n                                    \"USD\", \r\n                                    1.0, \r\n                                    description=\"XXXX paid me some money\"))\r\n    transactions.append(\r\n                        Transaction(\r\n                                    -2, \r\n                                    \"06-06-1966\", \r\n                                    \"USD\", \r\n                                    1.0, \r\n                                    description=\"I had to pay YYYYY some cash\"))\r\n    transactions.append(\r\n                        Transaction(\r\n                                    10000, \r\n                                    \"06-06-1966\", \r\n                                    \"BsF\", \r\n                                    0.0001, \r\n                                    description=\"Maduro paid me some money in Venezuelan BS. LOL\"))\r\n    account = Account(666666, \"Savings account\", transactions)\r\n    account.apply(Transaction(-3, \"02-28-1016\", \"USD\", 1.0, \"Coffee time\"))\r\n    print(\r\n          \"'{0}' Balance: ${1}, all in USD: {2}\".format(\r\n                                                        account.name, \r\n                                                        account.balance, \r\n                                                        account.all_usd))\r\n    account.save()\r\n    account.load()\r\n    print(\r\n          \"'{0}' Balance: ${1}, all in USD: {2}\".format(\r\n                                                        account.name, \r\n                                                        account.balance, \r\n                                                        account.all_usd))\r\n<\/pre>\n<p>Pickle no es seguro (ya que se lleva a cabo ninguna validaci\u00f3n en el c\u00f3digo leido desde el archivo), sin embargo es incre\u00edblemente conveniente para programas peque\u00f1os que requieren guardar datos r\u00e1pidamente con estructuras de datos complejas, como por ejemplo objetos anidados.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Muy f\u00e1cil de usar. Aqu\u00ed les muestro como grabar un objeto (Account) el cual tiene otros objetos adentro (lista de objetos tipo &#8216;Transaction&#8217;). #!\/usr\/bin\/env python3 # @author Jose Vicente Nunez &#8211; josevnz@kodeek.com import os, os.path, pickle, tempfile class Transaction: def __init__(self, amount, date, currency=&#8221;USD&#8221;, conv_rate=1.0, description=None): self.__amount = amount self.__date = date self.__currency = currency <a class=\"read-more\" href=\"http:\/\/kodegeek.com\/blog\/2016\/02\/27\/grabando-y-recuperando-datos-en-python-usando-pickle\/\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[239],"tags":[219,788,785,765,777,787,786],"_links":{"self":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/3732"}],"collection":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/comments?post=3732"}],"version-history":[{"count":8,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/3732\/revisions"}],"predecessor-version":[{"id":3743,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/3732\/revisions\/3743"}],"wp:attachment":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/media?parent=3732"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/categories?post=3732"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/tags?post=3732"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}