Python - 如何将实例变量值传递给描述符参数?
问题描述:
考虑下面的情况下,Python - 如何将实例变量值传递给描述符参数?
ITEMLIST类:
# filename: item_list.py
# locators dictionary is intentionally placed outside `ItemList` class
locators = {
'item_id': 'css=tr:nth-of-type({item_num}) .id',
'item_title': 'css=tr:nth-of-type({item_num}) .alert-rules',
# other properties
}
class ItemList(Item):
# --- these are data descriptors ---
# getting item_id value based on its item_num
item_id = TextReadOnly(locators['item_id'].format(item_num=self.item_num))
# getting item_title value based on its item_num
item_title = TextReadOnly(locators['item_title'].format(item_num=self.item_num))
def __init__(self, context, item_num=0):
# self.item_num can't be passed to locators
self.item_num = item_num
super(ItemList, self).__init__(
context
)
在这种情况下,我想通过self.item_num
值item_num
内定位符词典中ItemList
类。
原因是我想要item_id
和item_title
中的每一个都指特定的item_num
。
我卡在这一部分:
item_id = TextReadOnly(locators['item_id'].format(item_num=self.item_num))
item_title = TextReadOnly(locators['item_title'].format(item_num=self.item_num))
self.item_num
值不能被传递到定位器时,实例已经作出。
实现:
# filename: test.py
# print item_id values from item_num=1
item_1 = ItemList(context, 1)
print (‘Item_id_1: ’ + item_1.id)
# print item_id values from item_num=2
item_2 = ItemList(context, 2)
print (‘Item_id_2: ’ + item_2.id)
#^no result produced from item_1.id and item_2.id because self.item_num value can't be passed to locators
是否有可能从更新实例变量数据的描述符?
如何将实例变量值传递给数据描述符参数?
附加信息:
席力图召item_id
和item_title
作为实例属性,但没有运气。我注意到,数据描述符不能从这个帖子实例属性:Data descriptor should be a class attribute
项目类:
# filename: item.py
import abc
class Item(Page):
__metaclass__ = abc.ABCMeta
def __init__(self, context):
self.__context = context
super(Item, self).__init__(
self.__context.browser
)
描述:
# filename: text_read_only.py
class TextReadOnly(object):
def __init__(self, locator):
self.__locator = locator
def __get__(self, instance, owner=None):
try:
e = instance.find_element_by_locator(self.__locator)
except AttributeError:
e = instance.browser.find_element_by_locator(self.__locator)
return e.text
def __set__(self, instance, value):
pass
答
我发现this article并想出了解决方案添加描述符到一个对象。
低于该解决方案为我工作:
-
添加
__getattribute__
和__setattr__
到项目类# filename: item.py import abc class Item(Page): __metaclass__ = abc.ABCMeta def __init__(self, context): self.__context = context super(Item, self).__init__( self.__context.browser ) def __getattribute__(self, name): value = object.__getattribute__(self, name) if hasattr(value, '__get__'): value = value.__get__(self, self.__class__) return value def __setattr__(self, name, value): try: obj = object.__getattribute__(self, name) except AttributeError: pass else: if hasattr(obj, '__set__'): return obj.__set__(self, value) return object.__setattr__(self, name, value)
-
移动类属性为实例属性中ITEMLIST构造
# filename: item_list.py # locators dictionary is intentionally placed outside `ItemList` class locators = { 'item_id': 'css=tr:nth-of-type({item_num}) .id', 'item_title': 'css=tr:nth-of-type({item_num}) .alert-rules', # other properties } class ItemList(Item): def __init__(self, context, item_num=0): self.item_num = item_num # self.item_num is able to be passed to locators self.item_id = TextReadOnly(locators['item_id'].format(item_num=self.item_num)) self.item_title = TextReadOnly(locators['item_title'].format(item_num=self.item_num)) super(ItemList, self).__init__( context )
我认为你做错了 - 类属性不能取决于实例属性,因为类是首先初始化的。如果你想让'item_id'和'item_title'每个实例有所不同,为什么要把它们放在class属性中呢? – domoarrigato
Hello @domoarrigato:我将'item_id'和'item_title'设置为类属性,因为我想使用描述符** TextReadOnly **。我注意到[这篇文章](https://*.com/questions/12599972/descriptors-as-instance-attributes-in-python)数据描述符应该是一个类属性。是否有另一种方法来实现它? –
如果你想保留它们作为类的属性,你可以尝试使它们成为“受保护的类的属性”,参见[this] [1]的问题来看看如何。 在你的具体情况下,我认为这是矫枉过正,'item_id'和'item_title'看起来更像实例描述符而不是数据描述符,所以我将它们作为实例属性。 [1]:https://*.com/questions/5189699/how-to-make-a-class-property – Hrabal