diff --git a/point.py b/point.py
index 31f5311..be97735 100644
--- a/point.py
+++ b/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"""
diff --git a/propertize/__init__.py b/propertize/__init__.py
new file mode 100644
index 0000000..03fb55d
--- /dev/null
+++ b/propertize/__init__.py
@@ -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
diff --git a/propertize/convert_string.py b/propertize/convert_string.py
new file mode 100644
index 0000000..86c41f3
--- /dev/null
+++ b/propertize/convert_string.py
@@ -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()
\ No newline at end of file
diff --git a/propertize/propertize.py b/propertize/propertize.py
new file mode 100644
index 0000000..41c2ba5
--- /dev/null
+++ b/propertize/propertize.py
@@ -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
diff --git a/propertize/rename_attributes.py b/propertize/rename_attributes.py
new file mode 100644
index 0000000..97900a3
--- /dev/null
+++ b/propertize/rename_attributes.py
@@ -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