[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





_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to