Как изменить расположение строкового объекта на объект - PullRequest
0 голосов
/ 08 сентября 2018

Мне нужно преобразовать местоположение строкового объекта в объект. Мой код:

class Dog:
    def __init__(self,name):
        self.name= name

    def bark(self):
        print('BAR')

b=''

a=Dog('Test')
print(a)
with open('Dog.txt','w') as file:
   file.write(str(a))

with open('Dog.txt','r') as file:
   b=file.read()
   b=repr(b)

print(b)
b.bark()

Я сохранил объект a в Dog.txt файле <__main__.Dog object at 0x0000024E1C7AFE80>, и теперь я хочу взять эту строку и преобразовать ее в объект, чтобы я мог использовать с ней метод bark.

Как я могу это сделать

Ответы [ 3 ]

0 голосов
/ 08 сентября 2018

Вы не можете восстановить объект из его строкового представления. Вместо этого вы должны сериализовать объект перед тем, как поместить его в файл. Вы можете использовать pickle для этого

>>> a
<__main__.Dog object at 0x7f6d4ee8fb38>
>>> 
>>> pickle.dump(a, open('Dog.txt', 'wb'))
>>> b = pickle.load(open('Dog.txt', 'rb'))
>>> b
<__main__.Dog object at 0x7f6d4ee8fac8>
>>> b.bark()
BAR
0 голосов
/ 08 сентября 2018

И Медведь Браун, и Сунита не упоминают о том, что они предлагают сделать загрузку. может быть небезопасным. Для PyYAML это четко указано в начале учебник

Предупреждение: не безопасно вызывать yaml.load с любыми полученными данными. из ненадежного источника! yaml.load такой же мощный, как pickle.load и поэтому может вызывать любую функцию Python

Pickle имеет аналогичное предупреждение :

Предупреждение Модуль рассола не защищен от ошибочного или вредоносные данные. Никогда не распаковывать данные, полученные от ненадежный или не прошедший проверку подлинности источник

По крайней мере, используя YAML, нет необходимости рисковать сейчас или в будущем.

Сначала сделайте:

pip install ruamel.yaml

Тогда:

from ruamel.yaml import YAML

class Dog:
    # yaml_tag = u'!Doggie'
    def __init__(self, name):
        self.name = name

    def bark(self):
        print('BARK')

b = ''

a = Dog('Test')

yaml = YAML(typ='safe')
yaml.register_class(Dog)

with open('Dog.yaml','w') as ofp:
   yaml.dump(a, ofp)

with open('Dog.yaml') as ifp:
   b = yaml.load(ifp)

print(b.name, b)
b.bark()

print('==========')
with open('Dog.yaml') as ifp:
    print(ifp.read(), end='')

, что дает:

Test <__main__.Dog object at 0x7f88a5479320>
BARK
==========
!Dog {name: Test}

Примечания:

  • «Официальный» FAQ на yaml.org просит использовать .yaml в качестве файла расширение для файлов, содержащих YAML.
  • Вы можете раскомментировать строку "yaml_tag =", чтобы использовать другой тег в документе YAML. чем значение по умолчанию (т.е. ваше имя класса)
  • Мало того, что это безопасно, у этого также нет __main__ в файле YAML, который является важно, если вы когда-нибудь решите переместить определение класса в другой файл.
  • Хотя это и не так быстро, как использование маринада, описанное выше намного (~ 10x) быстрее, чем решение Медведь Браун предлагает. Это может быть актуально, если у вас есть 101 далматинец выгрузить и загрузить.
  • Это не заметно в данных вашего примера, но вышеупомянутые загружает / выгружает YAML в соответствии с Спецификация YAML 1.2 (опубликована в 2009 году), а также поддерживает устаревшую спецификацию YAML 1.1. PyYAML никогда не обновлялся и все еще поддерживает только YAML 1.1.

(Отказ от ответственности: я автор ruamel.yaml)

0 голосов
/ 08 сентября 2018

вы можете использовать PyYAML :

pip install PYyaml

и выгрузка и загрузка данных из файлов yaml:

In [1]: class Dog:
   ...:     def __init__(self,name):
   ...:         self.name= name
   ...: 
   ...:     def bark(self):
   ...:         print('BAR')
   ...: 
   ...: b=''
   ...: 
   ...: a=Dog('Test')
   ...: print(a)
   ...: 
   ...: 
<__main__.Dog object at 0x7fb082811390>

теперь выведите объект в yaml:

In [2]: import yaml

In [3]: with open('data.yml', 'w') as outfile:
   ...:     yaml.dump(a, outfile, default_flow_style=False)

внутри data.yml вы увидите:

!!python/object:__main__.Dog
name: Test

и теперь загружаем:

In [6]: with open('data.yml', 'r') as loadfile:
   ...:     data = yaml.load_all(loadfile)
   ...:     b = next(data)
   ...:     

In [7]: b
Out[7]: <__main__.Dog at 0x7fb07bfd5f28>

In [8]: b.bark()
BAR
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...