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 consts import CLOCKWISE
|
||||||
from qt5 import QtCore
|
from qt5 import QtCore
|
||||||
|
from propertize import propertize, rename_attributes, snake_case
|
||||||
|
|
||||||
|
|
||||||
|
@propertize("", "set")
|
||||||
|
@rename_attributes(snake_case)
|
||||||
class Point(QtCore.QPoint):
|
class Point(QtCore.QPoint):
|
||||||
"""
|
"""
|
||||||
Point of coordinates (x, y)
|
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):
|
def rotate(self, center, direction=CLOCKWISE):
|
||||||
""" Returns the Point image of the rotation of self
|
""" Returns the Point image of the rotation of self
|
||||||
through 90° CLOKWISE or COUNTERCLOCKWISE around center"""
|
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