2017-04-07 51 views
1

在我的情况下,我想保存和恢复文件中的一些“普通”变量(即整数,字符串),这最终将作为类属性。这个例子是我最近的地方,通过使用import纯文本,Python的语法文件来保存和恢复一些类变量?

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 *里面该类将它们作为类属性(self.aself.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 

...所以我得到一个丑陋的“SyntaxWarning:进口*只允许在模块级”,这是我不能让摆脱(除非我禁用警告,我不想这样做)

所以,我有其他选择,使用a.py(即纯文本,Python语法)编写的文件,并有在它的变量最终作为一些类属性?

(我见过How do I save and restore multiple variables in python?,但我不感兴趣pickleshelve,因为他们都没有在Python语法写,纯文本文件)

回答

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) 

Re结论:

{} 
hello 
+0

谢谢@StephenRauch - 我觉得我最喜欢这种方法,欢呼! – sdaau

+0

等待,但是'setattr(self,name,....)'会将'name'设置为*实例*属性,而不是类属性......尽管如此,您仍然可以在元类中执行此操作。或者使用'setattr(Teost,name,...)'设置一个类属性。 –

0

好了,找到了解决方法(它没有按”牛逼提高错误或警告) - 而不是import,读取该文件,然后exec(不evaleval SyntaxError: invalid syntax in python)它:

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

...虽然我也许应该感到不舒服使用exec ...

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的来源,那么这个问题不应该太大。

+0

谢谢@ juanpa.arrivillaga-很好也有这种方法;干杯! – sdaau

相关问题