如何获取实例属性列表
问题描述:
是否有一个函数可以获取类/ __init__
属性的列表而不需要单个对象。我需要类属性的名称将它传递给一个函数。我试图寻找一个解决方案很多小时,但他们大多数需要使用某事像x = ClassName()
- 在我的情况下,它会产生一个错误(例如__init__()
只需要6个参数(1给定))。 例如:如何获取实例属性列表
class Car:
def __init__(self, name, year, color):
self.name = name
self.year = year
self.color = color
如何得到这样的列表:
list_of_attr = ['name', 'year', 'color']
它甚至有可能?
编辑: 添加一些上下文到我的问题 - 我试图创建一个函数,它将从文本文件中获取数据并将其转换为对象列表。文件中的每行包含一个对象的数据 - 在上述情况下,它将是例如。 '沃尔沃,1995年,蓝'。 我现在有两个类和两个文件(但期望更多),我已经创建了工作解决方案,但现在我必须在预先写好的列表中将对象/实例属性的名称传递给我的函数。我希望自动完成,仅基于类名。
答
在你的课堂上根本没有任何课堂属性。您的__init__
方法设置实例属性,因此只有在实例已经运行并且__init__
实际运行后才能访问这些名称。
那时你可以通过vars()
function来获得一个实例的命名空间;这给你一个字典,这样你就可以拿到钥匙了:
vars(x).keys()
如果你正在寻找什么参数的__init__
方法需要,你可以使用inspect.getargspec()
内省签名。这给你所有参数的名称,以及任何默认值的值(所以关键字参数)。从这个可以推断出需要(位置)参数的个数:
import inspect
argspec = inspect.getargspec(Car.__init__)
required = argspec.args
if argspec.defaults:
required = required[:-len(argspec.defaults)]
这将包括self
论点自动绑定方法通过;你可以忽略第一个参数与切片:
method_required = argspec.args[1:]
if argspec.defaults:
method_required = method_required[:-len(argspec.defaults)]
演示:
>>> import inspect
>>> class Car:
... def __init__(self, name, year, color):
... self.name = name
... self.year = year
... self.color = color
...
>>> vars(Car('Volvo', 1975, 'blue'))
{'color': 'blue', 'name': 'Volvo', 'year': 1975}
>>> vars(Car('Volvo', 1975, 'blue')).keys()
['color', 'name', 'year']
>>> inspect.getargspec(Car.__init__)
ArgSpec(args=['self', 'name', 'year', 'color'], varargs=None, keywords=None, defaults=None)
答
总之,这是不可能的。如果没有为它创建内存,就无法获得memeber变量(意思是:你必须创建一个对象)。对此有一种替代方法,但唯一需要为__init__()
方法设置默认值。看看这个
class Car:
def __init__(self, name="default", year=1995, color="red"):
self.name = name
self.year = year
self.color = color
members = [mems for mems in dir(Car()) if not callable(mems) and not mems.startswith("__")]
print members
输出
['color', 'name', 'year']
“它甚至有可能?”不,因为这些是实例属性,而不是类属性。 – DeepSpace
这些是* instance *,而不是* class *,属性。你试图解决的实际问题是什么? – jonrsharpe
顺便说一句,在Python 2中,你的类应该明确地继承'object',即,“汽车类(对象):'否则你会得到旧式的课程。在Python 3中,所有的类都是新式的,但是你仍然可以使用这种语法,如果你想编写在两个版本中都可用的代码,这很方便。 –