Modifying __getattr__ to return a nested attribute instead of the named object
Do not write trivial getters/setters; this is not Java/C++/etc. It's more Pythonic to simply have everything public under most circumstances. Private-ness is not enforced anyway and is more of a suggestion.
Consider using @dataclass
You can drop empty parens after your class definition
Under what circumstances would it be possible for properties to be missing from DocumentObject? I'm not sure why you check for this. Won't it always be in vars?
Use type hints.
Use snake_case, not camelCase for variables
Do not allow arbitrary __setattr__ on your DocumentObject other than to registered properties
Do not accept a dict with redundant keys; just accept an iterable of properties
IMO it's less surprising to have the document's actual properties dict override any request to a property named &quot;properties&quot; than the other way around

Suggested:
from dataclasses import dataclass
from typing import Dict, Iterable, Union


@dataclass
class Property:
    name: str
    value: float  # ?? or maybe Any
    unit: str = 'mm'
    is_visible: bool = True


PropDict = Dict[str, Property]


class DocumentObject:
    def __init__(self, properties: Iterable[Property]):
        self.properties: PropDict = {p.name: p for p in properties}
        self.__setattr__ = self._setattr

    def __getattr__(self, name: str) -&gt; Union[PropDict, float]:
        if name == 'properties':
            return self.properties
        return self.properties[name].value

    def _setattr(self, key: str, value: float):
        self.properties[key].value = value


brick = DocumentObject((
    Property('length', 10),
    Property('width', 5),
))
print(brick.properties['length'].name)
print(brick.length)
brick.width = 7
print(brick.width)