[英]How to get attributes of parent class object only
我有2節課:
class Parent(object):
def __init__(self, id, name):
self.id = id
self.name = name
self.__parent_vars = ['id', 'name'] # make a copy
def print_values(self):
res = {}
for el in self.__parent_vars:
res[el] = vars(self)[el]
return res
class Child(Parent):
def __init__(self, id, name, last_name, age):
Parent.__init__(self, id, name)
self.last_name = last_name
self.age = age
我想做的-是從Parent
類的Child
參數獲取的。 我使用附加變量使它生效,但是我需要沒有附加變量的更優雅的解決方案。 我上泡菜課需要它。 如果我創建其他變量,它將破壞一個大項目中的架構。
我試圖找到這樣的東西:
c = Child(12,"Foo","whatever",34)
vars(c.super())
具有預期的輸出:
{'id': 12, 'name': 'Foo'}
我發現了這個問題: 僅在基類(Python)中獲得屬性,但是它與我的有很大的不同,所以我不能使用該解決方案。
恐怕你不容易。 在Python中,類僅包含方法和靜態屬性。 非靜態屬性通常存儲在對象的__dict__
屬性中。 這意味着,除非在特殊情況下,否則您不容易知道在父類方法,子類方法甚至任何方法之外分配了哪些屬性。
我只能想象一個meta_class可以檢測__init__
方法來存儲在調用期間更改了哪些屬性:
import collections
import functools
import inspect
class Meta_attr(type):
init_func = {}
attrs = collections.defaultdict(set)
def __new__(cls, name, bases, namespace, **kwds):
c = type.__new__(cls, name, bases, namespace, **kwds)
cls.init_func[c] = c.__init__
@functools.wraps(c.__init__)
def init(self, *args, **kwargs):
before = set(self.__dict__.keys())
cls.init_func[c](self, *args, **kwargs)
after = set(self.__dict__.keys())
cls.attrs[c].update(after.difference(before))
init.__signature__ = inspect.signature(c.__init__)
c.__init__ = init
return c
class Parent(object, metaclass=Meta_attr):
def __init__(self, id, name):
self.id = id
self.name = name
def print_values(self):
res = {}
for el in Meta_attr.attrs[Parent]:
res[el] = vars(self)[el]
return res
class Child(Parent):
def __init__(self, id, name, last_name, age):
Parent.__init__(self, id, name)
self.last_name = last_name
self.age = age
它給:
>>> c = Child(1,"a","b", 20)
>>> c.print_values()
{'id': 1, 'name': 'a'}
注意 :如果在__init__
方法之外設置了屬性,則此元類將不會注冊該屬性...
我找到了另一個解決方案。 看起來比較簡單,所以我用了。 它基於使用棉花糖模式。 另外,在我的項目中它更有用,因為我已經使用了棉花糖模式。 這個想法:我創建2個類和2個不同的模式。 並且可以僅使用父模式來序列化更大的類(子級):
class Parent(object):
def __init__(self):
self.id = 'ID'
self.name = 'some_name'
class Child(Parent):
def __init__(self):
Parent.__init__(self)
self.last_name = 'last_name'
self.age = 15
from marshmallow import Schema, fields, EXCLUDE
class ParentSchema(Schema):
ba = Parent()
id = fields.Str(missing=ba.id)
name = fields.Str(missing=ba.name)
class ChildSchema(Schema):
ba = Child()
id = fields.Str(missing=ba.id)
name = fields.Str(missing=ba.name)
last_name = fields.Str(missing=ba.last_name)
age = fields.Int(missing=ba.age)
user_data = {'id':'IDIDID', 'name':'add_name', 'last_name':'FAMILIYA'}
res = ParentSchema().load(user_data, unknown=EXCLUDE)
# output:
res
{'name': 'add_name', 'id': 'IDIDID'}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.