用于保存和恢复某些类变量的纯文本Python语法文件?

时间:2017-04-07 21:47:29

标签: python

在我的情况下,我想保存和恢复一些"普通"文件中的变量(即整数,字符串),最终将作为类属性。这个例子是我最接近的,使用import

a.py

b = 134
a = "hello"

mytest.py

import inspect

class Teost:
  from a import *
  def __init__(self):
    self.c = 12
    print(inspect.getmembers(self)) # has a and b
    print(self.__dict__)            # no a and b
    print(self.a)                   # prints "hello"

xx = Teost()

因此,此处a.py充当存储变量值(ab)的文件,而类中的from a import *将它们作为类属性({{ 1}}和self.a),这正是我想要的。

不幸的是,在一个类中使用星号self.b语法结果是不赞成的:

import

...所以我得到一个丑陋的"语法警告:导入*仅允许在模块级别",我无法摆脱(除非我禁用警告,我不想做)

那么,我是否还有其他选择,使用写为$ python mytest.py mytest.py:3: SyntaxWarning: import * only allowed at module level class Teost: [('__doc__', None), ('__init__', <bound method Teost.__init__ of <__main__.Teost instance at 0x7fdca368ab90>>), ('__module__', '__main__'), ('a', 'hello'), ('b', 134), ('c', 12)] {'c': 12} hello 的文件(即纯文本,Python语法),并将变量作为一些类属性?

(我已经看过How do I save and restore multiple variables in python?,但我对a.pypickle不感兴趣,因为它们都没有用Python语法写,纯文本文件)

3 个答案:

答案 0 :(得分:1)

我的意思是,你可以做一些超级黑客的事情:

import inspect
import a

class A:
  def __init__(self):
    self.c = 12
    print(('a', 'hello')  in inspect.getmembers(self)) # has a and b
    print(('b', 134) in inspect.getmembers(self))
    print('a' in self.__dict__)            # no a and b
    print('b' in self.__dict__)
    print(self.a)                   # prints "hello"

for name in dir(a):
    if not name.startswith('__'): # very brittle here
        val = vars(a)[name]
        setattr(A, name, val)

x = A()

您可能希望将上述逻辑包装在元类中。

也许只使用exec更清洁。如果您信任a.py的来源,那么问题就不会太大。

答案 1 :(得分:1)

您可以将模块导入您的班级,如:

<强>代码:

class Teost:
    import a as _a_py_attrs

    def __init__(self):
        for name in dir(Teost._a_py_attrs):
            if not name.startswith('__'):
                setattr(self, name, getattr(Teost._a_py_attrs, name))

测试代码:

xx = Teost()
print(xx.__dict__)
print(xx.a)

<强>结果:

{'a': 'hello', 'b': 134}
hello

作为类属性:

如果最好将这些作为类属性而不是实例属性,则可以执行以下操作:

class Teost:
    """ My Test Class """

import a as _a_py_attrs
for name in dir(_a_py_attrs):
    if not name.startswith('__'):
        setattr(Teost, name, getattr(_a_py_attrs, name))

测试代码:

xx = Teost()
print(xx.__dict__)
print(xx.a)

<强>结果:

{}
hello

答案 2 :(得分:0)

好吧,找到了一种解决方法(不会引发错误或警告) - 而不是import,请先阅读该文件,然后exec(不是eval,{{3它:

  #from a import *
  with open('a.py') as x: fstr = x.read()
  exec(fstr)

...虽然使用exec ...

我可能会觉得不舒服