如何将字符串对象的位置更改为对象

时间:2018-09-08 12:05:51

标签: python class object

我需要将字符串对象位置转换为对象。我的代码是:

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 :(得分:1)

您无法从其字符串表示形式恢复对象。相反,您应该序列化对象,然后再将其转储到文件中。您可以为此使用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

答案 1 :(得分:0)

您可以使用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

答案 2 :(得分:0)

Bear Brown和Sunitha均未提及他们提议进行的装载 可能是不安全的。对于PyYAML,这明确表示为at the start of the tutorial

  

警告:使用接收到的任何数据调用yaml.load是不安全的     来自不受信任的来源! yaml.load和pickle.load一样强大     因此可以调用任何Python函数

Pickle有a similar warning

  

警告腌制模块不能防止错误或不安全。     恶意构建的数据。切勿破坏从计算机接收到的数据     不受信任或未经身份验证的来源

至少使用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}

注意:

  • yaml.org上的“官方”常见问题解答要求对包含YAML的文件使用.yaml作为the file extension
  • 您可以取消注释“ yaml_tag =”行,以在YAML文档中使用其他标签 比默认值(即您的班级名称)
  • 这不仅安全,而且YAML文件中也没有__main__, 如果您决定将类定义移动到其他文件,则必不可少。
  • 尽管不如使用泡菜快,但上述速度比解决方案快很多(〜10倍) 熊布朗提议。如果您有101只斑点狗,这可能很重要 转储和加载。
  • 在示例数据中它并不明显,但是上面的内容根据 YAML 1.2规范(于2009年发布),还支持已过时的YAML 1.1规范。 PyYAML从未更新过,仍然仅支持YAML 1.1。

(免责声明:我是ruamel.yaml的作者)