Python descriptor protocol (for more or less structured data)

2013-07-30 Thread CWr
Hi together,

Some years ago I started a small WSGI project at my university. Since then the 
project was grown up every year. Some classes have more than 600 lines of code 
with (incl. boiler-plates mostly in descriptors/properties). 

Many of these properties are similar or have depencies among themselves.
The idea is to grouping similar properties like:

new style:
--
>>>m = MyClass(...)
>>>m.attr = 'some; complex:data#string'

>>>m.attr.value
'some'
>>>m.attr.extras
{'complex':('data','string')}

I wrote this descriptor:

class Descr:

def __init__(self, value):
self.attribute = self.__class__.__name__
self.__set__(None, value)

def __get__(self, obj, Type=None):
return getattr(obj, self.attribute, self)

def __set__(self, obj, value):
if obj is None: # descripting yourself
# do something here ...
self.value = value
else:
if hasattr(obj, self.attribute):
self.__get__(obj).__set__(None, value)
else:
setattr(obj, self.attribute, type(self)(value))

This works fine as long as the value attribute of Descr is read-only and the 
user have to use the descriptor interface e.g. __get__/__set__. Because
it's not guaranteed that the user gets a seperated instance of Descr which
will be living in obj.__dict__. If obj is None the descriptor will be returned
themselves.

But I would like that the user can use the following statement:

>>>m = MyClass(...)
>>>m.attr = 'some; complex:data#string'
>>>m.attr.value
'some'
>>>m.attr.value = 'some other'
>>>m.attr.value
'some other'

But this usage will be problematic. If the descriptor returned themselves 
(default case) and the user modified the value, he modified the default
value without to create a seperated instance attribute.

>>>class C:
>>>def __init__(self, value):
>>>if not value is None:
>>>self.attr = value
>>>attr = Descr('default value')

>>># explicit default usage (no problem): 
>>>C.attr.value
'default value'

>>>a = C()
>>>a.attr.value
'default value'

The following is the main Problem:

>>>a.attr.value = 'other'
>>>C.attr.value
'other'

The user could think that a new instance based value will be created. But it
isn't.

It will works fine only if I assign a value explicitly.

>>>m = MyClass(value='test')
>>>m.__dict__
>>>{'Descr':}

Has anyone had a similar problem in the past? Or I am on the wrong way.

Kind Regards,
Chris

Sorry for my terrible english ...





 





-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python descriptor protocol (for more or less structured data)

2013-07-31 Thread CWr
Peter, thanks for your response.
Sure, you are right when you say that's easier to use standard attribute 
assigning via __init__.

But my intention was:
- reducing the complexiticity of __init__
- avoiding boiler-plates (mostly property descriptors inside of the main class)
- creating instances (for complex data strings) only if they will be needed, 
otherwise use default instances (descriptors) 
- make it prossible that the data structure can be used in static context - 
like MyClass.attr - to get default values

Standard procedure:

>>>class C:
>>>def __init__(self, one, two=None, three=None, four=None, five=None, ...):
>>>if not two is None:
>>>self.two = Value(two)
>>>else:
>>>self.two = Value(self.DEFAULT_4_TWO)
>>>...

vs:

>>>class C:
>>>
>>>two = MyDescriptor('default for two')
>>>
>>>def __init__(self, one, two=None, three=None, four=None, five=None, ...):
>>>self.one = one
>>>if not two is None:
>>>self.two = two
>>>...

Probably it will be necessary to set the attribute at first access. 
Alternatively it may be possible to observe the descriptor til an attribute 
will be setted e.g. instance.attr.value = 'whatever'. At this point a new 
instance (like Value) should be created on obj.__dict__.

It's the procedure what I'm looking for. ;)

Kind Regards,
Chris
-- 
http://mail.python.org/mailman/listinfo/python-list


string processing - some problems whenever I have to parse a more complex string

2014-10-21 Thread CWr

Hello together,

currently I have to parse a string in an atomic way. Normally - in this case 
too - I have a counter variable to keep the current position inside the string. 
So far, I think this is the most flexible solution to do some lookaround's 
inside the string if necessary. Subroutines will be feed by the underlying data 
and the current position. A subroutine returns a tuple of the new position and 
the result. But I would like process subroutines with the same flexibillity 
(slicing/lookaround) but without returning the new position every again.

Is there any implementation like C++ StringPiece class? Or something like the 
following behavior:


>>>s = StringSlice('abcdef')
>>>s
StringSlice('abcdef') at xxx
>>>s[0]
'a'
>>>s.chop(1) # chop the first item
>>>s[0] # 'b' is the new first item
'b'
>>>s[:2]
'bc'
>>>s.chop(-1) # chop the last item
>>>s[-1]
'e'
>>>s[1:]
'cde'
>>>while s[0] != 'e':
   s.chop(1)
>>>s[0]
'e'
>>>s.startswith('e')
True
>>>s.isdigit()
False

Subroutines could chop the number of processed items internally if no error 
occours.

Another possibillty will be to chop the current item manually. But I don't know 
how efficient this is in case of large strings.

>>>while string:
   c = string[0]
   # process it ...
   string = string[1:]

But this assumes that I have to return rest of the string too and not useful for
my problem covered abrove.

Has anyone some tips what's the best practice to process a complex string, 
handling prositions in/and subroutines.

Thanks for all answers...
Cheers
Chris
-- 
https://mail.python.org/mailman/listinfo/python-list