Hello
I have the following code:
#### builder.py #########
class HtmlBuilder(object):
@staticmethod
def page(title=''):
return HtmlPage(title)
@staticmethod
def element(tag, text=None, **attribs):
return HtmlElement(tag, text, **attribs)
@staticmethod
def literal(text):
return HtmlLiteral(text)
class HtmlElementFactory(object):
def __init__(self):
for tag in ['li', 'ul']:
setattr( self, tag, HtmlBuilder.element(tag) )
#########################
and so I can do the following:
html = HtmlElementFactory()
ul = html.ul
ul.attrib['class'] = 'default'
for i in range(3):
li = html.li
li.text = 'ghfhj'
ul.append(li)
print ul.to_string()
but what I'd like to do is:
html = HtmlElementFactory()
ul = html.ul( class='default' )
for i in range(3):
ul.append( html.li( 'ghfhj' )
print ul.to_string()
ie. to pass along *args and **kwargs to the HtmlElement constructor.
Any suggestions? Or is there a better way to this kind of thing?
thanks
Gerard 10 1979
Gerard Flanagan wrote: Hello
I have the following code:
#### builder.py ######### class HtmlBuilder(object):
@staticmethod def page(title=''): return HtmlPage(title)
@staticmethod def element(tag, text=None, **attribs): return HtmlElement(tag, text, **attribs)
@staticmethod def literal(text): return HtmlLiteral(text)
Je ne vois pas très bien à quoi sert cette classe (à moins bien sûr
qu'il y ait d'autre code). Pour ce que je vois là, pourquoi ne pas
appeler directement les classes HtmlPage, HtmlElement et HtmlLiteral ?
Err... I don't see the point of this class. Why not just calling the
HtmlPage|Element|Literal classes directly ?
class HtmlElementFactory(object):
def __init__(self): for tag in ['li', 'ul']: setattr( self, tag, HtmlBuilder.element(tag) )
#########################
and so I can do the following:
html = HtmlElementFactory() ul = html.ul ul.attrib['class'] = 'default' for i in range(3): li = html.li li.text = 'ghfhj' ul.append(li) print ul.to_string()
but what I'd like to do is:
html = HtmlElementFactory() ul = html.ul( class='default' )
for i in range(3): ul.append( html.li( 'ghfhj' ) print ul.to_string()
'to_string' ?
Let's see... 'to_string', a class with only staticmethods in it...
You're coming from Java, aren't you ?-)
(if yes, google for "python is not java", it may be helpful)
ie. to pass along *args and **kwargs to the HtmlElement constructor. Any suggestions?
yes : pass along *args and **kwargs to the HtmlElement constructor !-)
Or is there a better way to this kind of thing?
yes again : kiss (Keep It Simple Stupid)
There's not enough code to really grasp what you're trying to do, but
from what I see, I'd say you're having a bad case of arbitrary
overcomplexification.
What's wrong with:
# nb: class is a reserved word in Python
ul = HtmlElement('ul', css_class='default')
for i in range(3):
ul.append(HtmlElement('li', 'baaz%d' % i)
# nb2: use the __str__() method of HtmlElement
print str(ul)
Python's philosophy is to make simple things simple (don't worry,
there's still space for complex things -> descriptors, metaclasses etc).
HTH
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Gerard Flanagan wrote: I have the following code:
#### builder.py ######### class HtmlBuilder(object):
@staticmethod def page(title=''): return HtmlPage(title)
@staticmethod def element(tag, text=None, **attribs): return HtmlElement(tag, text, **attribs)
@staticmethod def literal(text): return HtmlLiteral(text)
just curious, but what's the purpose of this class, and what gave
you the idea to structure your program in this way ?
</F>
bruno at modulix wrote: Gerard Flanagan wrote: Hello
I have the following code:
#### builder.py ######### class HtmlBuilder(object):
@staticmethod def page(title=''): return HtmlPage(title)
@staticmethod def element(tag, text=None, **attribs): return HtmlElement(tag, text, **attribs)
@staticmethod def literal(text): return HtmlLiteral(text) Je ne vois pas très bien à quoi sert cette classe (à moins bien sûr qu'il y ait d'autre code). Pour ce que je vois là, pourquoi ne pas appeler directement les classes HtmlPage, HtmlElement et HtmlLiteral ?
C'est une vaine tentative d'appliquer "the Factory Pattern" ! J'ai eu
commence d'ecrire les classes 'ul(HtmlElement), li(HtmlElement), etc ',
et le but de 'HtmlElementFactory' etait d'eviter ceci (cela?). Il y a
une recette ici: http://aspn.activestate.com/ASPN/Coo...n/Recipe/86900
mais il utilise 'apply', qui est...blah
I was trying to implement the factory pattern.
The recipe above uses 'apply' which is deprecated according to the
docs, and I suppose I was curious how to do the same sort of thing
without 'apply'.
Err... I don't see the point of this class. Why not just calling the HtmlPage|Element|Literal classes directly ?
class HtmlElementFactory(object):
def __init__(self): for tag in ['li', 'ul']: setattr( self, tag, HtmlBuilder.element(tag) )
#########################
and so I can do the following:
html = HtmlElementFactory() ul = html.ul ul.attrib['class'] = 'default' for i in range(3): li = html.li li.text = 'ghfhj' ul.append(li) print ul.to_string()
but what I'd like to do is:
html = HtmlElementFactory() ul = html.ul( class='default' )
for i in range(3): ul.append( html.li( 'ghfhj' ) print ul.to_string()
'to_string' ? Let's see... 'to_string', a class with only staticmethods in it... You're coming from Java, aren't you ?-)
Never been to Java in my life!
I don't know if I understand you, HtmlElement has a 'to_string' method
but no static methods:
class HtmlElement(list):
def __init__(self, tag, text=None, **attrib):
self.tag = tag
self.text = text
self.attrib = attrib
def write(self, writer):
writer.start(self.tag, self.attrib)
if self.text is not None:
writer.data(self.text)
for node in self:
node.write(writer)
writer.end()
def to_string(self):
out = StringIO()
writer = HtmlWriter(out)
self.write(writer)
ret = out.getvalue()
out.close()
return ret
(if yes, google for "python is not java", it may be helpful)
ie. to pass along *args and **kwargs to the HtmlElement constructor. Any suggestions? yes : pass along *args and **kwargs to the HtmlElement constructor !-)
Or is there a better way to this kind of thing?
yes again : kiss (Keep It Simple Stupid)
There's not enough code to really grasp what you're trying to do, but from what I see, I'd say you're having a bad case of arbitrary overcomplexification.
My code itself is just a learning project ( etant sans emploi a ce
moment, moi-meme...) and it is no doubt a bit 'over-egged' at the
minute, but it is a first attempt and I can always refactor later.
What's wrong with:
# nb: class is a reserved word in Python ul = HtmlElement('ul', css_class='default') for i in range(3): ul.append(HtmlElement('li', 'baaz%d' % i)
# nb2: use the __str__() method of HtmlElement print str(ul)
Python's philosophy is to make simple things simple (don't worry, there's still space for complex things -> descriptors, metaclasses etc).
HTH -- bruno desthuilliers python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in 'o****@xiludom.gro'.split('@')])"
Merci bien pour votre reponse.
Gerard
Fredrik Lundh wrote: Gerard Flanagan wrote:
I have the following code:
#### builder.py ######### class HtmlBuilder(object):
@staticmethod def page(title=''): return HtmlPage(title)
@staticmethod def element(tag, text=None, **attribs): return HtmlElement(tag, text, **attribs)
@staticmethod def literal(text): return HtmlLiteral(text)
just curious, but what's the purpose of this class, and what gave you the idea to structure your program in this way ?
</F>
In my defense, I can only quote Albert Einstein: "If we knew what it
was we were doing, it would not be called research, would it?" I'm
writing a script to generate a few relatively static webpages and
upload them to a server, but it's as much a learning exercise as
anything else - I have no formal programming education. I thought the
Factory pattern would be appropriate here; the class you quote was a
first attempt and i knew it was undoubtedly the wrong approach, so
that's why i asked the group...
Gerard
Gerard Flanagan wrote: http://aspn.activestate.com/ASPN/Coo...n/Recipe/86900
mais il utilise 'apply', qui est...blah
I was trying to implement the factory pattern. The recipe above uses 'apply' which is deprecated according to the docs, and I suppose I was curious how to do the same sort of thing without 'apply'.
Apply has been replaced by 'extended call syntax', that is why it is
deprecated. Instead of
return apply(self._function,_args,_kargs)
write
return self._function(*_args, **_kargs)
Kent
bruno at modulix wrote:
(snip) Je ne vois pas très bien à quoi sert cette classe (à moins bien sûr qu'il y ait d'autre code). Pour ce que je vois là, pourquoi ne pas appeler directement les classes HtmlPage, HtmlElement et HtmlLiteral ?
oops, sorry, forgot to remove this before posting :(
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Gerard Flanagan wrote: bruno at modulix wrote:
(snip french) I was trying to implement the factory pattern. The recipe above uses 'apply' which is deprecated according to the docs, and I suppose I was curious how to do the same sort of thing without 'apply'.
def fun(*args, **kwargs):
pass
def otherfun(*args, **kwargs):
fun(*args, **kwargs) Err... I don't see the point of this class. Why not just calling the HtmlPage|Element|Literal classes directly ?
(snip)
'to_string' ? Let's see... 'to_string', a class with only staticmethods in it... You're coming from Java, aren't you ?-)
Never been to Java in my life!
bad guess.
I don't know if I understand you, HtmlElement has a 'to_string' method
I don't know this HtmlElement class, nor where it comes from.
'to_string()' (or is it toString() ?) is javaish. The pythonic idiom for
this is implementing the __str__() method and calling str(obj) on the
obj (which will call obj.__str__()). Hence my (bad) guess about you
being a Javaer.
but no static methods:
Not the HtmlElement class, but the HtmlBuilder one. Here again, a class
defining only staticmethods is a pretty javaish idiom - in Python, we
just use good old functions !-) (in a separate module if you want a
separate namespace).
class HtmlElement(list):
def __init__(self, tag, text=None, **attrib): self.tag = tag self.text = text self.attrib = attrib
def write(self, writer): writer.start(self.tag, self.attrib) if self.text is not None: writer.data(self.text) for node in self: node.write(writer) writer.end()
def to_string(self): out = StringIO() writer = HtmlWriter(out) self.write(writer) ret = out.getvalue() out.close() return ret
If it's your own code, you may want to rename this last method __str__(). ie. to pass along *args and **kwargs to the HtmlElement constructor. Any suggestions?
yes : pass along *args and **kwargs to the HtmlElement constructor !-)
Or is there a better way to this kind of thing?
yes again : kiss (Keep It Simple Stupid)
There's not enough code to really grasp what you're trying to do, but from what I see, I'd say you're having a bad case of arbitrary overcomplexification.
My code itself is just a learning project ( etant sans emploi a ce moment, moi-meme...) and it is no doubt a bit 'over-egged' at the minute, but it is a first attempt and I can always refactor later.
My experience is that it's far easier to start simple and add
flexibility where needed than to simplify useless complexity. KISS,
yagni and all that kind of things... Merci bien pour votre reponse.
You're welcome.
BTW, there's also a french speaking python newsgroup at fr.comp.lang.py.
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
bruno at modulix wrote:
[...] I don't know this HtmlElement class, nor where it comes from. 'to_string()' (or is it toString() ?) is javaish. The pythonic idiom for this is implementing the __str__() method and calling str(obj) on the obj (which will call obj.__str__()). Hence my (bad) guess about you being a Javaer.
I've made this change, thanks. ( I had a year with C# so maybe that's
why I'm so idiomatically-challenged ! )
Not the HtmlElement class, but the HtmlBuilder one. Here again, a class defining only staticmethods is a pretty javaish idiom - in Python, we just use good old functions !-) (in a separate module if you want a separate namespace).
But it's personal preference, no? The functions were kind of related
and meaningless outside the module they were declared - but I'll take
it on board, anyway.
[...] My experience is that it's far easier to start simple and add flexibility where needed than to simplify useless complexity. KISS, yagni and all that kind of things...
yagni - I'd never heard that one!
I've ditched the factory class in any case: http://gflanagan.net/site/python/htm...HtmlBuilder.py
(FWIW) Merci bien pour votre reponse.
You're welcome.
BTW, there's also a french speaking python newsgroup at fr.comp.lang.py.
I wasn't aware of that, I'll have a lurk!
Thanks again.
Gerard
-- bruno desthuilliers python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in 'o****@xiludom.gro'.split('@')])"
Gerard Flanagan wrote: bruno at modulix wrote: [...]
I don't know this HtmlElement class, nor where it comes from. 'to_string()' (or is it toString() ?) is javaish. The pythonic idiom for this is implementing the __str__() method and calling str(obj) on the obj (which will call obj.__str__()). Hence my (bad) guess about you being a Javaer.
I've made this change, thanks. ( I had a year with C# so maybe that's why I'm so idiomatically-challenged ! )
Well, C# being somewhat inspired by Java... Not the HtmlElement class, but the HtmlBuilder one. Here again, a class defining only staticmethods is a pretty javaish idiom - in Python, we just use good old functions !-) (in a separate module if you want a separate namespace).
But it's personal preference, no?
Well, in Python, there are a lot of things that can be done the way you
like it, but are better done the idiomatic way. Python relies quite a
lot on conventions and idioms where other languages try to inforce
strict rules.
The functions were kind of related and meaningless outside the module they were declared -
FWIW (and from the snippet I saw), these functions are useless even in
the module !-)
Unless you want to dynamically choose the concrete class at runtime
based on platform/settings/phase of the moon/whatnot (which seems not to
be te case in the snippet you posted), you don't need these functions,
just instanciating the concrete class is enough. Remember that Python
classes *are* factory already - and that you can freely replace a class
by any callable returning an instance, ie:
== before refactoring, directly instanciating concrete class ==
# myhtmlmodule.py
class HtmlElement(tag, *args, **kw):
# code here
# myclientmodule.py
from myhtmlmodule import HtmlElement
ul = HtmlElement('ul')
== after refactoring, using a factory function ==
# myhtmlmodule.py
class _HtmlElement1(tag, *args, **kw):
# code here
class _HtmlElement2(tag, *args, **kw):
# other code here
# yes, it's now a function...
def HtmlElement(tag, *args, **kw):
if phase_of_the_moon():
klass = _HtmlElement1
else:
klass = _HtmlElement2
return klass(tag, *args, **kw)
# myclientmodule.py
# well... nothing changed here !-)
from myhtmlmodule import HtmlElement
ul = HtmlElement('ul')
You could also do the trick with metaclass black magic, but what, KISS...
but I'll take it on board, anyway.
[...]
My experience is that it's far easier to start simple and add flexibility where needed than to simplify useless complexity. KISS, yagni and all that kind of things...
yagni - I'd never heard that one!
You Aint Gonna Need It.
Code not written is the best code, so don't write code "just in case".
Python is usually dynamic enough to make refactoring easy (cf example above)
I've ditched the factory class in any case:
http://gflanagan.net/site/python/htm...HtmlBuilder.py (FWIW)
Seems mostly clean. May I suggest a couple small corrections/improvements ?
1/ potential bugfix:
try:
from tidy import parseString
except ImportError:
def parseString(text):
# woops, this function is supposed to return something
#pass
return text
2/ safer and cleaner
class HtmlPage(HtmlElement):
# removed class vars,
# replaced with default in __init__
def __init__(self, title, **kw):
self.title = title
self.stylesheets = kw.get('stylesheets', [])
self.doctype = kw.get('doctype', HTML4_STRICT) BTW, there's also a french speaking python newsgroup at fr.comp.lang.py.
I wasn't aware of that, I'll have a lurk!
see you there !-) -- bruno desthuilliers python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in 'o****@xiludom.gro'.split('@')])"
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
bruno at modulix wrote: Gerard Flanagan wrote: The functions were kind of related and meaningless outside the module they were declared - FWIW (and from the snippet I saw), these functions are useless even in the module !-)
ok, ok... :-)
Unless you want to dynamically choose the concrete class at runtime based on platform/settings/phase of the moon/whatnot (which seems not to be te case in the snippet you posted), you don't need these functions, just instanciating the concrete class is enough. Remember that Python classes *are* factory already - and that you can freely replace a class by any callable returning an instance, ie:
== before refactoring, directly instanciating concrete class == # myhtmlmodule.py class HtmlElement(tag, *args, **kw): # code here
# myclientmodule.py from myhtmlmodule import HtmlElement ul = HtmlElement('ul')
== after refactoring, using a factory function == # myhtmlmodule.py class _HtmlElement1(tag, *args, **kw): # code here
class _HtmlElement2(tag, *args, **kw): # other code here
# yes, it's now a function... def HtmlElement(tag, *args, **kw): if phase_of_the_moon(): klass = _HtmlElement1 else: klass = _HtmlElement2 return klass(tag, *args, **kw)
# myclientmodule.py # well... nothing changed here !-) from myhtmlmodule import HtmlElement ul = HtmlElement('ul')
ah, I'm getting it. I've ditched the factory class in any case:
http://gflanagan.net/site/python/htm...HtmlBuilder.py (FWIW) Seems mostly clean. May I suggest a couple small corrections/improvements ?
1/ potential bugfix: try: from tidy import parseString except ImportError: def parseString(text): # woops, this function is supposed to return something #pass return text
2/ safer and cleaner class HtmlPage(HtmlElement): # removed class vars, # replaced with default in __init__ def __init__(self, title, **kw): self.title = title self.stylesheets = kw.get('stylesheets', []) self.doctype = kw.get('doctype', HTML4_STRICT)
That's much better - thanks very much for taking the time, I'm a little
bit wiser!
regards
Gerard
-- bruno desthuilliers python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in 'o****@xiludom.gro'.split('@')])" This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Eric |
last post by:
Slightly off topic, i know, but here goes:
I'm trying to xlate a module of mine to C++. Only problem is, it makes
heavy use of "setattr". Anyone know a straightforward way to do
"setattr" in C++...
|
by: Gerson Kurz |
last post by:
I stumbled across this (while using my homebrewn enum class):
class test:
pass
instance = test()
setattr(instance, "THIS :*2+~# IS OBVIOUSLY INVALID", 123)
I would've expected some kind of...
|
by: kramb64 |
last post by:
I'm trying to use setattr inside a module.
From outside a module it's easy:
import spam
name="hello"
value=1
setattr(spam, name, value)
But if I want to do this inside the module spam...
|
by: Alex |
last post by:
I apologize for asking maybe a very trivial question.
I have a new class object A with slots. One of the slots is, for
example, object spam. Object spam, in turn, also has slots and one of
them...
|
by: Paulo da Silva |
last post by:
Hi!
In a class C, I may do setattr(C,'x',10).
Is it possible to use getattr/setattr for variables not inside
classes or something equivalent? I mean with the same result as
exec("x=10").
...
|
by: Donn Ingle |
last post by:
Hi,
Here's some code, it's broken:
class Key( object ):
def __init__(self):
self.props = KeyProps()
def __getattr__(self, v):
return getattr( self.props,v )
def __setattr__(self,var,val):
|
by: Rotlaus |
last post by:
2 weeks ago i asked for a etended getattr() which worked really fine,
but now i would love to have a extended setattr() as well.
Lets assume i have some classes:
class A(object):
def...
|
by: maestro |
last post by:
Why are these functions there? Is it somehow more idiomatic to use
than to do obj.field ?
Is there something you can with them that you can't by obj.field
reference?
|
by: Bojan Mihelac |
last post by:
Hi all - when trying to set some dynamic attributes in class, for
example:
class A:
for lang in :
exec('title_%s = lang' % lang) #this work but is ugly
# setattr(A, "title_%s" % lang, lang) #...
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
| |