uzumaki already provided one metaclass as a possible solution to the question asked above, but here is another with example usage. Following an attempt to create a Child
class, another way of making it difficult to override methods is shown. Putting two underscores before but not after an attribute name will automatically cause name mangling to be invoked. See this answer to another question for an easy-to-use way of accessing this ability manually.
#! /usr/bin/env python3
class Access(type):
__SENTINEL = object()
def __new__(mcs, name, bases, class_dict):
private = {key
for base in bases
for key, value in vars(base).items()
if callable(value) and mcs.__is_final(value)}
if any(key in private for key in class_dict):
raise RuntimeError('certain methods may not be overridden')
return super().__new__(mcs, name, bases, class_dict)
@classmethod
def __is_final(mcs, method):
try:
return method.__final is mcs.__SENTINEL
except AttributeError:
return False
@classmethod
def final(mcs, method):
method.__final = mcs.__SENTINEL
return method
class Parent(metaclass=Access):
@Access.final
def do_something(self):
"""This is where some seriously important stuff goes on."""
pass
try:
class Child(Parent):
def do_something(self):
"""This should not be allowed."""
pass
except RuntimeError:
print('Child cannot be created.')
class AnotherParent:
def __do_something(self):
print('Some seriously important stuff is going on.')
def do_parent_thing(self):
self.__do_something()
class AnotherChild(AnotherParent):
def __do_something(self):
print('This is allowed.')
def do_child_thing(self):
self.__do_something()
example = AnotherChild()
example.do_parent_thing()
example.do_child_thing()