【发布时间】:2012-07-06 10:31:20
【问题描述】:
我正在尝试使用__get__ 描述符对某种类型的数据创建一个思考代理,以便客户端代码可以方便地使用它(最好通过示例显示):
class Value(object):
def __init__(self, val):
self.val = val
def __get__(self, instance, owner):
return self.val
class Container(object):
x = Value(1)
y = [ Value(2), Value(3) ]
c = Container()
assert c.x == 1
assert c.y[0] == 2 # fails.
现在,我主要知道它为什么会失败,所以我想知道是否有更好的方法来实现我的目标,即包装数据,这样当客户端访问它时,他们只需直接访问 Value 对象(在实际上,__get__ 方法会在返回之前对 self.val 做一些事情)
详情
我正在尝试解决的实际案例是实用程序代码,用于协助编写 PageObjects 和 PageElements 用于 selenium 测试用例。我想为测试作者提供一种简洁的方式来编写表单的PageObjects:
class MyLogin(PageObject):
username_text_box = PageElement(By.ID, "username")
password_text_box = PageElement(By.ID, "password")
submit_button = PageElement(By.CLASS_NAME, "login-button")
driver = webdriver.Firefox()
driver.get("http://mypage.com")
login_page = MyLogin(driver)
login_page.username_text_box.send_keys("username01")
login_page.password_text_box.send_keys("XXXX")
login_page.submit_button.click()
我正在尝试将获取实际WebElement 的业务封装在 PageElement 类中,并且我希望允许客户端在访问 PageElement 对象后能够访问 WebElement。能够拥有列表,字典有助于使 PageObject 实例更清晰,并对相关的 PageElements 进行分组。
【问题讨论】:
-
如您所见,描述符只能用作类属性。如果您能提供更多详细信息,将更容易为您找到解决方案。
-
在python中创建代理对象的常用方法是使用
__getattr__(也可能是__setattr__)模拟代理对象的行为。除非在新式类的成员案例中,否则您的方式将行不通。 -
为什么不试试 y = Value((2,1)) 而不是 y = [ Value(2), Value(3) ]