如何知道哪个属性和对象具有指定值
How to know which attribute and object has a specified value
我是 python 的新手,非常感谢您对我的问题的帮助。
我有一个class A和三个子classB、C、D,它们都继承自A——像这样。
class A:
def __init__(self, arg1, arg2, arg3):
self.attr1 = B
self.attr2 = C
self.attr3 = D
class B(A):
name = name
other = other
class C(A):
name = name
other = other
class D(A):
name = name
other = other
我想写一个具有以下含义的全局方法:
"If the input attribute is not equal to ANY of the attributes listed in the specified Object, then take the input attribute from WHATEVER Object B, C, D has it"。我以为我可以像这样实现代码。
def GlobalMethod(self, input):
if input != self.__dict__:
getattr(A, name=input)
print('attribute found here:'+getattr(self.name))
else:
print('attribute not found')
将实例分配给 subclasses
b = B()
c = C()
d = D()
我最终会像这样传递值(为了示例,我只写一个实例)
GlobalMethod(b, 'big bang')
主要问题:
getattr() 没有关键字参数,因为错误类型 returns.
我不太清楚如何实现"ANY of the attributes"。我认为 dict 可能是个好方法。
我不太清楚如何实现"from WHATEVER Object B, C, D has it"
提前感谢您的帮助! (抱歉,如果我的描述和代码很乱)
如果您要在 A
的实例中查找属性值,您只需将它们全部放入一个池中并扫描它以获取匹配的对象。
所以:
class MappingPool:
def __init__(self):
self.pool = []
def add_scannable_object(self, obj):
self.pool.append(obj)
def search(self, some_value):
for obj in self.pool:
for attr in obj.__dict__:
if getattr(obj, attr) == some_value:
return obj
应该return 找到第一个包含与所需值匹配的属性的对象。我将搜索限制在实例属性上,不包括 class 属性,因为您似乎只对这些属性感兴趣。 (在 A.__init__
中定义的那些。)
要使用它:
mapping = MappingPool()
b = B('a','b','c')
c = C('test','d','e')
d = D('f','g','h')
mapping.add_scannable_object(b)
mapping.add_scannable_object(c)
mapping.add_scannable_object(d)
x = mapping.search('test') # x is now an alias to c
更新以回应评论并澄清属性和 class 属性
您放入映射池的对象不受限制。对于它的价值,您可以在其中放入任何具有 __dict__
属性的内容。任何 class 和任何 class 的任何实例都是合适的。 IE。如果除了 A
、B
、C
和 D
class 之外,您还定义:
class Test:
where_is_it = 5
def __init__(self):
it_is_here = 9
然后,您可以将 Test
的任何实例添加到您用来放置 b
、c
和 d
的相同 MappingPool
中,如图所示多于。因此:
mapping = MappingPool()
b = B('a','b','c')
c = C('test','d','e')
d = D('f','g','h')
test = Test()
mapping.add_scannable_object(b)
mapping.add_scannable_object(c)
mapping.add_scannable_object(d)
mapping.add_scannable_object(test)
x = mapping.search(9)
print(x is test) # prints True
当我说搜索不包括 class 属性时,我想警告的是,使用上面的设置,mapping.search(5)
returns None
即使 test.where_is_it
是 5
.
这是因为实例变量和 class 变量是在两个不同的命名空间中定义的,并且仅使用 obj.__dict__
return 实例的命名空间。
您可以通过输入 test.__dict__
which returns {'it_is_here': 9}
说服自己。那么 where_is_it
属性去了哪里呢?在 class 命名空间中,因为它是在 class 级别定义的:
>>> test.__class__.__dict__
mappingproxy({'__dict__': <attribute '__dict__' of 'Test' objects>, '__weakref__': <attribute '__weakref__' of 'Test' objects>, '__doc__': None, '__init__': <function Test.__init__ at 0x7f4bf6f09d08>, '__module__': '__main__', 'where_is_it': 5})
因此,如果您需要同时考虑正在扫描的对象的实例属性和 class 属性,那么您需要将两者结合起来:
from itertools import chain
for attr in chain(test.__dict__, test.__class__.__dict__):
print(attr)
输出:
it_is_here
__dict__
__weakref__
__doc__
__init__
__module__
where_is_it
结论,如果您想在实例属性之上支持 class 属性,只需将 for attr in obj.__dict__:
替换为 for attr in chain(obj.__dict__, obj.__class__.__dict__):
。
我是 python 的新手,非常感谢您对我的问题的帮助。
我有一个class A和三个子classB、C、D,它们都继承自A——像这样。
class A:
def __init__(self, arg1, arg2, arg3):
self.attr1 = B
self.attr2 = C
self.attr3 = D
class B(A):
name = name
other = other
class C(A):
name = name
other = other
class D(A):
name = name
other = other
我想写一个具有以下含义的全局方法: "If the input attribute is not equal to ANY of the attributes listed in the specified Object, then take the input attribute from WHATEVER Object B, C, D has it"。我以为我可以像这样实现代码。
def GlobalMethod(self, input):
if input != self.__dict__:
getattr(A, name=input)
print('attribute found here:'+getattr(self.name))
else:
print('attribute not found')
将实例分配给 subclasses
b = B()
c = C()
d = D()
我最终会像这样传递值(为了示例,我只写一个实例)
GlobalMethod(b, 'big bang')
主要问题:
getattr() 没有关键字参数,因为错误类型 returns.
我不太清楚如何实现"ANY of the attributes"。我认为 dict 可能是个好方法。
我不太清楚如何实现"from WHATEVER Object B, C, D has it"
提前感谢您的帮助! (抱歉,如果我的描述和代码很乱)
如果您要在 A
的实例中查找属性值,您只需将它们全部放入一个池中并扫描它以获取匹配的对象。
所以:
class MappingPool:
def __init__(self):
self.pool = []
def add_scannable_object(self, obj):
self.pool.append(obj)
def search(self, some_value):
for obj in self.pool:
for attr in obj.__dict__:
if getattr(obj, attr) == some_value:
return obj
应该return 找到第一个包含与所需值匹配的属性的对象。我将搜索限制在实例属性上,不包括 class 属性,因为您似乎只对这些属性感兴趣。 (在 A.__init__
中定义的那些。)
要使用它:
mapping = MappingPool()
b = B('a','b','c')
c = C('test','d','e')
d = D('f','g','h')
mapping.add_scannable_object(b)
mapping.add_scannable_object(c)
mapping.add_scannable_object(d)
x = mapping.search('test') # x is now an alias to c
更新以回应评论并澄清属性和 class 属性
您放入映射池的对象不受限制。对于它的价值,您可以在其中放入任何具有 __dict__
属性的内容。任何 class 和任何 class 的任何实例都是合适的。 IE。如果除了 A
、B
、C
和 D
class 之外,您还定义:
class Test:
where_is_it = 5
def __init__(self):
it_is_here = 9
然后,您可以将 Test
的任何实例添加到您用来放置 b
、c
和 d
的相同 MappingPool
中,如图所示多于。因此:
mapping = MappingPool()
b = B('a','b','c')
c = C('test','d','e')
d = D('f','g','h')
test = Test()
mapping.add_scannable_object(b)
mapping.add_scannable_object(c)
mapping.add_scannable_object(d)
mapping.add_scannable_object(test)
x = mapping.search(9)
print(x is test) # prints True
当我说搜索不包括 class 属性时,我想警告的是,使用上面的设置,mapping.search(5)
returns None
即使 test.where_is_it
是 5
.
这是因为实例变量和 class 变量是在两个不同的命名空间中定义的,并且仅使用 obj.__dict__
return 实例的命名空间。
您可以通过输入 test.__dict__
which returns {'it_is_here': 9}
说服自己。那么 where_is_it
属性去了哪里呢?在 class 命名空间中,因为它是在 class 级别定义的:
>>> test.__class__.__dict__
mappingproxy({'__dict__': <attribute '__dict__' of 'Test' objects>, '__weakref__': <attribute '__weakref__' of 'Test' objects>, '__doc__': None, '__init__': <function Test.__init__ at 0x7f4bf6f09d08>, '__module__': '__main__', 'where_is_it': 5})
因此,如果您需要同时考虑正在扫描的对象的实例属性和 class 属性,那么您需要将两者结合起来:
from itertools import chain
for attr in chain(test.__dict__, test.__class__.__dict__):
print(attr)
输出:
it_is_here
__dict__
__weakref__
__doc__
__init__
__module__
where_is_it
结论,如果您想在实例属性之上支持 class 属性,只需将 for attr in obj.__dict__:
替换为 for attr in chain(obj.__dict__, obj.__class__.__dict__):
。