2016-12-16 139 views
-1

是否有一個函數可以獲取類/ __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年,藍'。 我現在有兩個類和兩個文件(但期望更多),我已經創建了工作解決方案,但現在我必須在預先寫好的列表中將對象/實例屬性的名稱傳遞給我的函數。我希望自動完成,僅基於類名。

+2

「它甚至有可能?」不,因爲這些是實例屬性,而不是類屬性。 – DeepSpace

+1

這些是* instance *,而不是* class *,屬性。你試圖解決的實際問題是什麼? – jonrsharpe

+0

順便說一句,在Python 2中,你的類應該明確地繼承'object',即,「汽車類(對象):'否則你會得到舊式的課程。在Python 3中,所有的類都是新式的,但是你仍然可以使用這種語法,如果你想編寫在兩個版本中都可用的代碼,這很方便。 –

回答

3

在你的課堂上根本沒有任何課堂屬性。您的__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) 
1

總之,這是不可能的。如果沒有爲它創建內存,就無法獲得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'] 
+0

我真的很喜歡你的答案。我想我可以使用我的實例的默認值。我也對它進行了一些修改,所以它排除了方法(我知道我沒有在我的問題中包含任何內容):'[mems for mems in dir(Car())if callable(getattr(Car(),mems))和不mems.startswith(「__」)]' – 10ok

+0

看起來像一個很好的修改@ 10ok,謝謝! –

+0

雖然我遇到了該解決方案的問題。它會自動排列非常不想要的名稱。 – 10ok