Формирование объектов на лету. Реализация на python


(Mykhailo Poliarush) #1

Выполняю очередную задачу по автоматизации решил немного упростить себе жизнь за счет формирования объектов на лету с помощью метаклассов 

'''
Created on Nov 20, 2010
@author: polusok
'''
pageClass = "LoginPage"
pageBaseClass = "Page"
elementClass = "Ok"
elementBaseClass = "Button"

class Page(object):
    def getUrl(self):
        return "http://url"

class Button(object):
    def click(self, xpath):
        print "Click is triggered on xpath="+xpath

page = eval("type(pageClass, (%(p)s,), {})()" % {'p':pageBaseClass})
page.ok = eval("type(elementClass, (%(b)s,), {})()" % {'b':elementBaseClass})

if __name__ == '__main__':
    print page.getUrl()
    page.ok.click("//xpath[condition]")

Если есть какие-то замечания, буду рад выслушать плюсы и минусы.

 


(Mykhailo Poliarush) #2

ссылки по теме 

http://onlamp.com/pub/a/python/2003/04/17/metaclasses.html?page=1
http://www.python.org/download/releases/2.2/descrintro/
http://docs.python.org/library/functions.html#type
http://www.eggheadcafe.com/software/aspnet/35914170/create-a-class-at-runtime.aspx
http://stackoverflow.com/questions/3483718/when-to-inline-definitions-of-metaclass-in-python
http://blog.ianbicking.org/a-conservative-metaclass.html 


(Mykhailo Poliarush) #3

TypeType = type(type)

class dom():
    __slots__ = ('Body', 'Button', 'Div')
    __ddd__ = None
    __body__ = None
    def __init__(self, body, slots=None):
        self.__body__ = body
        if slots:
            self.__slots__ = slots
        
    def __getattr__(self, name):
        domClasses = [j for (i,j) in globals().items() if isinstance(j, TypeType) and issubclass(j, dom)]
        for domClass in domClasses:
            # Instead of slots you can parse HTML to guess whether you can map
            # $name on any of its elements and instantiate appropriate Class basing
            # on it.
            # if self.__body__.find(name) != -1
            #     # Some fancy logic there
            #     if name == domClass.__name__:
            #         return domClass(self.__body__.retrieve_this_part_of_the_dom(name))
            if name in self.__slots__:
                if name == domClass.__name__:
                    return domClass()
        raise ValueError('Can\'t instantiate')
            
class Body(dom):
    __slots__ = ()
    def getUrl(self):
        print("http://url")

class Button(dom):
    __slots__ = ()
    def click(self, xpath):
        print("Click is triggered on xpath="+xpath)

class Div(dom):
    __slots__ = ('Body', 'Button', 'Div')
    def setHtml(self, html):
        print("Html is set to"+html)

def main():
    myDom = dom('HTML to parse')
    myDom.Body.getUrl()
    myDom.Button.click('qwe')
    myDom.Div.setHtml('123')
    myDom.Div.Div.setHtml('123')
    myDom.Div.Body.Div
if __name__ == "__main__":
    main()

(Mykhailo Poliarush) #4

еще один пример использования питона для формирования объектов на лету 

from types import ClassType
from selenium import selenium
import unittest

IPS = ['192.168.0.1', '192.168.0.2']
BROWSERS = ['safari', 'chrome']

class SomeUnitTest(object):

    def test_something(self):
        sel = self.selenium
        # test code

def main(base):
    suites = []
    results = unittest.TestResult()

    for iidx, ip in enumerate(IPS):
        for bidx, browser in enumerate(BROWSERS):
            def setUp(self):
                self.verificationErrors = []
                self.selenium = selenium("localhost", 4444, "*%s" % self.browser, "http://%s/" % self.ip)
                self.selenium.start()

            def tearDown(self):
                self.selenium.stop()
                self.assertEqual([], self.verificationErrors)

            ut = ClassType('UT_%i_%i' % (iidx, bidx), (unittest.TestCase, base), {'ip': ip, 'browser': browser})
            ut.setUp = setUp
            ut.tearDown = tearDown

            suites.append(unittest.TestLoader().loadTestsFromTestCase(ut))

    unittest.TestSuite(suites)(results)
    for obj, error in results.errors:
        print 'In: ', obj
        print error

if __name__ == "__main__":
    main(SomeUnitTest)


(2Elf) #5

Здравствуйте.
Почему такая каша ? Это у меня одного так отображается ?
http://clip2net.com/s/6jmOfd


(Mykhailo Poliarush) #6

@2Elf исправлено