Создание объекта Python 3 из файла
Хорошо, я застрял. Я пытался загрузить файл с сериализованной строкой из функции сохранения Ауры и получить объект для работы с ним.
Файл выглядит так:
PkgState {timeOf = SimpleTime {yearOf = 2013, monthOf = February, dayOf = 13, hourOf = 15, minuteOf = 38}, pkgsOf = fromList [("a52dec",[0,7,4,6]),("aalib",[1,4,5,9]),("abs",[2,4,4,1]),("acl",[2,2,51,3]),("acsccid",[1,0,4,1]),("alsa-lib",[1,0,26,1]),("alsa-oss",[1,0,25,1]),("alsa-plugins",[1,0,26,1]),("alsa-utils",[1,0,26,1]),("alsaequal",[0,6,7]),("android-sdk-platform-tools",[16,0,1,2]),("android-udev",[1,6,1]),("anki-beta",[2,0,7,1]),("apache",[2,2,23,1]),("apr",[1,4,6,1]),("apr-util",[1,5,1,1]),("archey",[20121216,1]),("archlinux-keyring",[20130127,1]),("archlinux-themes-slim",[1,2,3]),("aria2",[1,16,3,1]),("asciidoc",[8,6,8,1]),("aspell",[0,60,6,1,1]),("aspell-en",[7,1,2]),("at-spi2-atk",[2,6,2,1]),("at-spi2-core",[2,6,3,1]),("atk",[2,6,0,1]),("attr",[2,4,46,2]),("aura",[1,1,3,0,1]),("autoconf",[2,69,1]),("autofs",[5,0,7,1]),("automake",[1,13,1,1]),("avahi",[0,6,31,5]),("babl",[0,1,10,1]),("bash",[4,2,42,3]),("bc",[1,6,8]),("beecrypt",[4,2,1,5]),("binutils",[2,23,1,3]),("bison",[2,7,1]),("blueman",[1,23,5]),("bluez",[4,101,1]),("bridge-utils",[1,5,1]),("bzip2",[1,0,6,4]),("c-ares",[1,9,1,1]),("ca-certificates",[20130119,1]),("ca-certificates-java",[20120608,1]),("cackey",[0,6,8,1]),("cairo",[1,12,12,2]),("cairo-perl",[1,82,2]),("caps",[0,9,6,1]),("cdparanoia",[10,2,4]),("cdrdao",[1,2,3,6]),("cdrkit",[1,1,11,2]),("chromium",[24,0,1312,70,1]),("chromium-pepper-flash",[11,6,602,167,1]),("cifs-utils",[5,9,1]),("cloog",[0,18,0,1])}
Это было сокращено. Я могу разобрать это вручную (что, скорее всего, будет боль). Есть ли какие-то, чтобы начать с этого и получить объект?
Или, поскольку Aura была написана на haskell, я должен просто использовать haskell?
1 ответ
Я полагаю, что лучше всего сохранить ауру в формате JSON вместо использования Show
а также Read
экземпляров. Это может быть не проще, чем сделать одноразовый парсер в Python, но это будет более длительное изменение сообщества. РЕДАКТИРОВАТЬ: Если это не очевидно, по моему мнению, было бы действительно лучше просто использовать Haskell, так что все, что вам нужно сделать, это fmap read (readFile path)
разбор, но я привык, что это не практичный вариант для многих программистов с короткими временными рамками.
Шаг 1: Получить код ауры
git clone https://github.com/fosskers/aura.git
cd aura
Шаг 2: Найдите, где он понимает что-то по имени PkgState
:
grep 'writeFile' * -R
Шаг 3: измените формат (который в настоящее время используется show
) для использования JSON через пакет aeson:
+{-# LANGUAGE OverloadedStrings #-}
+import qualified Data.ByteString.Lazy.Char8 as BL
+ import Data.Aeson
...
- liftIO $ writeFile filename (show state)
+ liftIO $ BL.writeFile filename (encode state)
Шаг 4: Шаг 3 действительно не сделан, нам нужно ToJSON
случаи для этого вызова encode
работать.
+{-# LANGUAGE OverloadedStrings #-}
+ import Data.Aeson
+ instance ToJSON PkgState of
+ toJSON (PkgState t p) = object [ "timeOf" .= t, "pkgsOf" .= p ]
И в Aura/Time.hs
:
+ {-# LANGUAGE OverloadedStrings #-}
...
+ import Data.Aeson
...
+ instance ToJSON SimpleTime of
+ toJSON (SimpleTime y m d h n) = object [ "yearOf" .= y
+ , "monthOf" .= fromEnum m
+ , "dayOf" .= d
+ , "hourOf" .= h
+ , "minuteOf" .= n
+ ]
Шаг 5: Чтобы сделать эту сборку, нам нужно добавить пакет aeson в build-deps
в aura.cabal
,
Шаг 6: Это может работать для ваших целей, но было бы лучше, чтобы аура могла загружать файлы, которые были закодированы в JSON:
-import Data.Maybe (mapMaybe)
+import Data.Maybe (mapMaybe, fromMaybe)
+import Control.Applicative
+import Control.Monad
...
+instance ToJSON PkgState where
+ toJSON (PkgState t p) = object [ "timeOf" .= t, "pkgsOf" .= p ]
+
+instance FromJSON PkgState where
+ parseJSON (Object v) = PkgState <$> v .: "timeOf" <*> v .: "pkgsOf"
+ parseJSON _ = mzero
+
...
-readState name = liftIO (read `liftM` readFile (stateCache </> name))
-
+readState name = liftIO ((fromMaybe err . decode) `liftM` BL.readFile (stateCache </> name))
+ where err = error "Package State unrecognized"
и снова в Aura/Time.hs
+
+instance FromJSON SimpleTime where
+ parseJSON (Object v) = SimpleTime <$> v .: "yearOf"
+ <*> (toEnum `fmap` (v .: "monthOf"))
+ <*> v .: "dayOf"
+ <*> v .: "hourOf"
+ <*> v .: "minuteOf"
+
Я оставлю Python-декодирование этого JSON-объекта вам.