Use my new super module propertize
This commit is contained in:
parent
68cf21392c
commit
f13962890f
6
point.py
6
point.py
@ -4,16 +4,16 @@
|
||||
|
||||
from consts import CLOCKWISE
|
||||
from qt5 import QtCore
|
||||
from propertize import propertize, rename_attributes, snake_case
|
||||
|
||||
|
||||
@propertize("", "set")
|
||||
@rename_attributes(snake_case)
|
||||
class Point(QtCore.QPoint):
|
||||
"""
|
||||
Point of coordinates (x, y)
|
||||
"""
|
||||
|
||||
x = property(QtCore.QPoint.x, QtCore.QPoint.setX)
|
||||
y = property(QtCore.QPoint.y, QtCore.QPoint.setY)
|
||||
|
||||
def rotate(self, center, direction=CLOCKWISE):
|
||||
""" Returns the Point image of the rotation of self
|
||||
through 90° CLOKWISE or COUNTERCLOCKWISE around center"""
|
||||
|
41
propertize/__init__.py
Normal file
41
propertize/__init__.py
Normal file
@ -0,0 +1,41 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Class decorators:
|
||||
|
||||
@propertize buids derived classes
|
||||
with a properties for each attribute with accessors
|
||||
|
||||
@convert_attributes_name buids derived classes
|
||||
with attributes name converted by a function
|
||||
|
||||
Accessors are found among the class's methods (its callable attributes)
|
||||
if the method's name start with getters_prefix or setters_prefix.
|
||||
If getters_prefix is "", creates property for each method named "method_name"
|
||||
only if a setter named "setters_prefix"+"method_name" is found and vice_versa.
|
||||
Attributes are named by their accessors' name minus the prefix.
|
||||
You can use @rename_attributes(snake_case) to rename all class' attributes
|
||||
|
||||
:Example:
|
||||
|
||||
>>> from propertize import propertize, snake_case
|
||||
>>> class AccessorsClass:
|
||||
... def __init__(self):
|
||||
... self._private_attribute = 0
|
||||
... def getAttribute(self):
|
||||
... return self._private_attribute
|
||||
... def setAttribute(self, value):
|
||||
... self._private_attribute = value
|
||||
...
|
||||
>>> @propertize("get", "set")
|
||||
... @rename_attributes(snake_case)
|
||||
... class PropertiesClass(AccessorsClass): pass
|
||||
...
|
||||
>>> instance = PropertiesClass()
|
||||
>>> instance.attribute = 1
|
||||
>>> instance.attribute
|
||||
1
|
||||
"""
|
||||
|
||||
from .convert_string import snake_case
|
||||
from .rename_attributes import rename_attributes
|
||||
from .propertize import propertize
|
14
propertize/convert_string.py
Normal file
14
propertize/convert_string.py
Normal file
@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
|
||||
|
||||
first_cap_re = re.compile('(.)([A-Z][a-z]+)')
|
||||
all_cap_re = re.compile('([a-z0-9])([A-Z])')
|
||||
|
||||
def snake_case(s):
|
||||
"""
|
||||
Convert a CamelCase string to snake_case
|
||||
"""
|
||||
|
||||
s1 = first_cap_re.sub(r'\1_\2', s)
|
||||
return all_cap_re.sub(r'\1_\2', s1).lower()
|
49
propertize/propertize.py
Normal file
49
propertize/propertize.py
Normal file
@ -0,0 +1,49 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from collections import defaultdict
|
||||
|
||||
"""
|
||||
Class decorator building derived classes
|
||||
with a properties for each hidden attribute with accessors
|
||||
"""
|
||||
|
||||
def propertize(
|
||||
getters_prefix = "get_",
|
||||
setters_prefix = "set_"
|
||||
):
|
||||
"""
|
||||
:param getters_prefix: methods starting with this prefix will be considered as getters
|
||||
:type getters_prefix: str
|
||||
:param setters_prefix: methods starting with this prefix will be considered as setters
|
||||
:type setters_prefix: str
|
||||
:return: a derived class with a properties for each attribute with accessors
|
||||
:return type: type
|
||||
"""
|
||||
|
||||
def _propertize(cls):
|
||||
if not getters_prefix and not setters_prefix: return cls
|
||||
|
||||
properties_accessors = defaultdict(dict)
|
||||
for method_name in dir(cls):
|
||||
for accessor_type, prefix in ("getter", getters_prefix), ("setter", setters_prefix):
|
||||
if method_name.startswith(prefix):
|
||||
try:
|
||||
method = getattr(cls, method_name)
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
if callable(method):
|
||||
property_name = method_name[len(prefix):]
|
||||
properties_accessors[property_name][accessor_type] = method
|
||||
|
||||
class propertizeClass(cls):
|
||||
pass
|
||||
|
||||
for property_name, accessors in properties_accessors.items():
|
||||
getter = accessors.get("getter", None)
|
||||
setter = accessors.get("setter", None)
|
||||
if (getters_prefix or setter) and (setters_prefix or getter):
|
||||
setattr(propertizeClass, property_name, property(getter, setter))
|
||||
|
||||
return propertizeClass
|
||||
|
||||
return _propertize
|
34
propertize/rename_attributes.py
Normal file
34
propertize/rename_attributes.py
Normal file
@ -0,0 +1,34 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Class decorator building derived classes
|
||||
with all attributes renamed by a function
|
||||
"""
|
||||
|
||||
|
||||
def rename_attributes(convert_function):
|
||||
"""
|
||||
:param function_to_convert_name: function used to convert attributes' names
|
||||
:type function_to_convert_name: callable
|
||||
:return: a derived class with renamed attributes
|
||||
:return type: type
|
||||
"""
|
||||
|
||||
def _rename_attributes(cls):
|
||||
if not convert_function: return cls
|
||||
|
||||
class ConvertedCase(cls):
|
||||
pass
|
||||
|
||||
for attribute_name in dir(cls):
|
||||
try:
|
||||
attribute = getattr(cls, attribute_name)
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
new_name = convert_function(attribute_name)
|
||||
if new_name != attribute_name:
|
||||
setattr(ConvertedCase, new_name, attribute)
|
||||
|
||||
return ConvertedCase
|
||||
|
||||
return _rename_attributes
|
Loading…
x
Reference in New Issue
Block a user