[Tutor] [Re: class/type methods/functions]
spir
denis.spir at free.fr
Thu Oct 30 21:07:00 CET 2008
[forwarded, only A.T.Hofkamp got this answer]
A.T.Hofkamp a écrit :
> spir wrote:
>> Q: Is there a way to write /type/ (class) functions, meaning methods
not bound to an instance, in python?
>
> As Bob Gailer already said, staticmethod seems to do what you want.
Thank you for you answers about static methods. I will explore that
path. Seems to be what I was looking for.
>
> After reading your mail, I cannot help wondering that something
crucial seems to be missing in your class structure. (I get the
impression that you are trying to squeeze object information and object
meta information together in one class definition.)
>
Yes. This is a consequence of type & instance beeing defined in the same
class() code section. If I unserstand well, what you call
meta_information is for me simply type attributes. They will be
available to any object of this type. Is this a misuse of types/classes?
See also below for some more precisions.
This syntax that mixes type and object definition applies to all OOP
languages, no? That's why we need a syntactic rule to distinguish type &
instance attributes. In python, the way I understand it, the prefix
'self.' (or any other special name) plays that role. It works for
properties, i.e. non-method attributes. But the syntax chosen for method
definition (with self written as argument instead of prefixed) makes it
impossible: it seems that any method has to be bound to an instance.
> The examples you give are however too fragmented for me, to
understand the underlying problem you are trying to solve.
>
Unfortunately, I can't paste right now a full & real snippet of the, as
it is beeing refactored: it would rather be confusing. Here is a kind of
outline of a typical symbol type:
class Format(Symbol):
''' block formats symbol '''
# import relevant config data for this symbol type
from_codes = config.formats.from_codes
to_codes = config.formats.to_codes
names = config.formats.names
# open_format to be checked with closing tag (xhtml only)
open_format = None
def __init__(self, source, mark, section_level, posV, posH, close =
False,
list_type = None, list_level=0):
# posV & posH ~ line & element numbers for error output
# 'mark' can be a wiki code or an xhfml tag
self.section_level = section_level # = current title level
self.indent = section_level * TAB # for nicer xhtml output
self.close = close # for automatic
closing (wiki only)
self.list_level = list_level # nesting level
self.list_type = list_type # bullet or number
self.error = False # flag used for no output
# read & record symbol data
if source == WIKI:
self.from_wiki(mark, posV, posH)
return
if source == XHTML:
self.from_xhtml(mark, posV, posH)
def from_wiki(self, code, posV, posH):
''' Define formats name.
Record whether it's an opening or closing mark.'''
[...]
def from_xhtml(self, tag, posV, posH):
''' Define formats code. '''
[...]
def into_wiki(self):
if self.error or self.close:
return ''
if self.name == LIST_ITEM: # case of a list
code = Format.to_codes[self.list_type]
code *= self.list_level
else:
code = Format.to_codes[self.name]
if code in header_block_codes:
code *= self.section_level
return code + SPACE
def into_xhtml(self):
if self.error:
return ''
return write_tag(self.name, self.close, DIV, self.section_level)
def to_table():
''' write symbol data into plain text, table-like, format
(for test or export to DB) '''
[...]
(Note: by the way, native english speakers may tell me if the
identifiers & comments seem clear -- the original program was in french
-- but I will probably share it later. One of reasons of the rebuilding.)
So, as you can see, symbols of the Format type will use data held by
their type. This seems rather an obvious and consistent practice to me.
Namely, the from_codes, to_codes and names type attributes are available
to future Format instances. these attributes were imported from an
config module/object built at startup (from a config file).
The main process for building a sequence of symbols is (simplified):
* A function reads the source file step by step. Actually, it is a
method of kind of state machine. Let's say the source is an xhtml doc
(wiki codes vary much and are much less regular and more ambiguous).
* When it steps on a format tag (e.g. <li> for a lit item), it launches
the creation of a format object, thus an instance of the Format type.
Clear? Passes to it as argument relevant actual data of the parsing
process, especially 'mark', that in this case holds the tag.
* The format will "read itself" from the tag, meaning it will record
that it is an opening tag, a 'list item', and, say, one of the bullet
kind. That'all for this kind of simple example.
That is more or less the way a representation of the source text is built.
The writing process is more straighforword. A (very) simplified outline
may be:
for symbol in tortue.symbols: # I called the state machine'turtle' ;-)
out_file.write(symbol.into_wiki()) # case of writing into wiki lang
The symbols even take care of line feeds & consistent indentation!
Now, imagine it was a wiki text instead, and the user wishes to output
it into a wiki language different of the one it was originally coded in.
At some time between the reading & writing will the config been rebuilt
and, as a consequence, data held by Symbol types. As this is an action
of the type, I wish it to be performed by the type. So:
class Format(Symbol):
''' block formats symbol '''
# import relevant config data for this symbol type
def config(): # should be a type method (static?)
from_codes = config.formats.from_codes
to_codes = config.formats.to_codes
names = config.formats.names
> Have you considered using the factory pattern? (ie make an object
that represents the type, and another one for the data) In that way you
can nicely seperate both kinds of information.
>
Definitely! That is the pattern I'm using -- or trying. I didn't know it
has a name. Now, isn't this factory<->object pattern precisely what the
type<->instance relationship is supposed to be?
Now, I admit that in my particuliar case, the types/classes need the
full potential of real objects:
* config ==> type properties
* config change at runtime ==> type methods
>
> Sincerely,
> Albert
>
If anyone of you wishes to comment/criticize the "exploration" part of
my previous post, welcome!
Thank you all for your advices.
denis
More information about the Tutor
mailing list