2017-04-07 50 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

相關問題