纯文本,Python语法文件来保存和恢复一些类变量?
在我的例子中,我希望在一个文件中保存和恢复一些“普通”变量(即int、string),这些变量最终将作为类属性。这个例子是我使用纯文本,Python语法文件来保存和恢复一些类变量?,python,Python,在我的例子中,我希望在一个文件中保存和恢复一些“普通”变量(即int、string),这些变量最终将作为类属性。这个例子是我使用import得到的最接近的例子: a.py b = 134 a = "hello" import inspect class Teost: from a import * def __init__(self): self.c = 12 print(inspect.getmembers(self)) # has a and b prin
import
得到的最接近的例子:
a.py
b = 134
a = "hello"
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()
mytest.py
b = 134
a = "hello"
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
充当存储变量值(a
和b
)的文件,类内导入的将它们作为类属性(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 mytest.py
mytest.py:3:SyntaxWarning:import*仅允许在模块级别
Teost类:
[(“文件”,“无”),(“初始化”,“模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块”,“主模块
{'c':12}
你好
。。。所以我得到了一个难看的“SyntaxWarning:import*只允许在模块级别”,我无法摆脱它(除非我禁用警告,我不想这样做)
那么,我还有其他选择吗,使用一个写为a.py
(即纯文本、Python语法)的文件,并将其中的变量作为一些类属性结束
(我看过,但我对pickle
或shelve
不感兴趣,因为它们都不是用Python语法编写的纯文本文件)好吧,找到了一个解决方法(不会引起错误或警告)-而不是导入,读取文件,然后执行exec
(不是eval
),它:
。。。虽然使用exec
我可能会感到不舒服,我的意思是,你可以做一些超级黑客的事情:
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
的源代码,那么问题应该不会太大。您可以将模块导入到类中,如下所示:
代码:
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
xx = Teost()
print(xx.__dict__)
print(xx.a)
{}
hello
测试代码:
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
xx = Teost()
print(xx.__dict__)
print(xx.a)
{}
hello
结果:
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
xx = Teost()
print(xx.__dict__)
print(xx.a)
{}
hello
作为类属性:
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
xx = Teost()
print(xx.__dict__)
print(xx.a)
{}
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))
测试代码:
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
xx = Teost()
print(xx.__dict__)
print(xx.a)
{}
hello
结果:
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
xx = Teost()
print(xx.__dict__)
print(xx.a)
{}
hello
谢谢@Stephernauch-我想我最喜欢这种方法,干杯!等等,但是setattr(self,name,…)
将name
设置为实例属性,而不是类属性。。。不过,你可以在元类中这样做。或者使用setattr(Teost,name,…)
设置一个类属性。谢谢@juanpa.arrivillaga-也很高兴记住这种方法;干杯