2017-08-17 196 views
2

想,如果我有一個類,如下圖所示,如何創建一個Python對象的所有字段和屬性的字典?

class TestClass(object): 

    def __init__(self): 
     self.name = 'Marty' 
     self.age = 25 
     self.place = 'CL' 

    @property 
    def country(self): 
     return 'USA' 

    @property 
    def age_group(self): 
     return '18-25' 

我想創建一個字典出所有的@properties的。我試過__dict__vars,但仍然沒有出現@property。我怎樣才能包括@property

>>> x = TestClass() 
>>> x.__dict__ 
{'age': 25, 'name': 'Marty', 'place': 'CL'} 
>>> vars(x) 
{'age': 25, 'name': 'Marty', 'place': 'CL'} 

我想包括age_groupcountry與返回的值作爲鍵和值。

+0

您可以訪問TestClass .__ dict__上的屬性。所以我想你可以遍歷這些並添加名稱,如果'type == property' –

回答

3

使用字典理解,超過的對象迭代屬性:

obj = TestClass() 
object_dict = {attr: getattr(obj, attr) for attr in dir(obj)} 

如果你真的只想@property屬性,目前尚不清楚你的問題,你可以過濾對他們來說,像這樣:

object_properties_dict = {attr: getattr(obj, attr) for attr in dir(obj.__class__) if type(getattr(obj.__class__, attr)) is property} 
3

您可以通過在您的實例上調用dir來獲取所需的名稱。然而,由dir返回的列表也有一堆名稱,你不要想要(從object繼承的方法的名稱),所以我們需要過濾掉。

class TestClass(object): 
    def __init__(self): 
     self.name = 'Marty' 
     self.age = 25 
     self.place = 'CL' 

    @property 
    def country(self): 
     return 'USA' 

    @property 
    def age_group(self): 
     return '18-25' 

x = TestClass() 
d = {k: getattr(x, k) for k in dir(x) if not k.startswith('__')} 
print(d) 

輸出

{'age': 25, 'age_group': '18-25', 'country': 'USA', 'name': 'Marty', 'place': 'CL'} 

這裏是要做到這一點更清潔的方式。我們遍歷類對象的vars(),特別是查找實例爲property的項目。然後我們使用itertools.chain將這些名稱與在類的實例上調用vars()的名稱組合起來。

from itertools import chain 

class TestClass(object): 
    def __init__(self): 
     self.name = 'Marty' 
     self.age = 25 
     self.place = 'CL' 

    @property 
    def country(self): 
     return 'USA' 

    @property 
    def age_group(self): 
     return '18-25' 

    def do_stuff(self): 
     return 'hello' 

def attributes_and_properties(obj): 
    props = (k for k, ktype in vars(type(obj)).items() 
     if isinstance(ktype, property)) 
    return {k: getattr(obj, k) for k in chain(props, vars(obj))} 

x = TestClass() 
print(attributes_and_properties(x)) 

輸出

{'country': 'USA', 'age_group': '18-25', 'name': 'Marty', 'age': 25, 'place': 'CL'} 

這種方法優於以前的技術,因爲這些代碼也將包括綁定方法,其名稱不與__開始,像do_stuff,在它的輸出。

+0

OP狀態在哪裏,他不希望繼承屬性? –

+0

@RichardNeumann問題的最後一行說:「我想包含'age_group'和'country',並將返回的值作爲鍵和值。」換句話說,除了他的代碼當前正在打印的實例屬性之外,他只需要那些_property_鍵值對。你的代碼也打印了一堆方法,我不認爲他需要這些方法。 –

相關問題