Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
纯文本,Python语法文件来保存和恢复一些类变量?_Python - Fatal编程技术网

纯文本,Python语法文件来保存和恢复一些类变量?

纯文本,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

在我的例子中,我希望在一个文件中保存和恢复一些“普通”变量(即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
    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-也很高兴记住这种方法;干杯