如何从.py文件中获取包含类定义的属性名称

时间:2014-01-16 14:52:19

标签: python python-2.7

我得到的输入文件只包含一个类定义(类只是常量容器,包含json的键,类似的文件用于Java客户端解码json)看起来像:

class Constants(object):

    VERSION= 'version'
    OS = 'os'
    PROGRAM = 'program'
    # more constants .....

如何获取Constants中定义的所有属性的字典,如何将文件解析为字典? 我想压缩密钥并生成具有相同常量键但更短键的新.py和.java文件。

4 个答案:

答案 0 :(得分:2)

>>> [elem for elem in dir(Constants) if not elem.startswith("_")]
['OS', 'PROGRAM', 'VERSION']

答案 1 :(得分:2)

  1. 导入模块
    • 我在以下代码中使用imp.load_module代替__import__来导入abitrary文件路径。
  2. 找到类对象。
  3. 使用vars
  4. 迭代class属性
    import imp
    path = '/path/to/file'
    with open(path, 'U') as f:
        mod = imp.load_module('temporary', f, path, ('.py', 'U', imp.PY_SOURCE))
    
    builtins = vars(__builtins__)
    cls = next(value for name, value in vars(mod).items() if name not in builtins)
    const_dict = {name: value for name, value in vars(mod.Constants).items()
                              if not name.startswith('_')}
    print(const_dict)
    
    # => {'OS': 'os', 'VERSION': 'version', 'PROGRAM': 'program'}
    

    在2.7.6,3.3.2,3.4.0b2上用Python测试。

答案 2 :(得分:1)

扩大答案第一:

# dir(yourClass) will get you all the methods and properties of yourClass and parents wheather yourClass
# is a definition or an instance
elements = [elem for elem in dir(Constants) if not elem.startswith("_")]

# Using yourClass.__dict__.keys() will give you the same of dir if applied to a definition but only instance members 
# if applied to an instance
elements = [elem for elem in Constants.__dict__.keys() if not elem.startswith("_")]

# You can get to the values of the properties with
for el in elements:
    print Constants.__dict__[el]
    # plus whatever you want to do to those elements

# Or if you're using the __dict__ way
Constants.__dict__.items()

答案 3 :(得分:1)

以下是使用execfile和python 2.6(我在Debian Wheezy上工作)的示例。还给出了为python 2.7及更高版本构建字典的较短版本。 constants.py文件可以定义几个类,所有这些类都将被解析。

#!/usr/bin/env python

d = {}
const_d = {}

execfile("constants.py", d)

for k,cls in d.items():
  if k not in vars(__builtins__):
    if type(cls) is type:
      # Python version < 2.7
      attributes = {}
      for name, value in vars(cls).items():
        if not name.startswith('__'):
          attributes[name] = value
      # Python version >= 2.7
      #attributes = {name: value for name, value in vars(cls).items() if not name.startswith('__')}
      const_d[cls.__name__] = attributes
      pass
    pass
  pass

print(const_d)