67 lines
1.8 KiB
Python
67 lines
1.8 KiB
Python
from functools import wraps
|
|
from time import perf_counter, sleep
|
|
from typing import Self
|
|
|
|
|
|
def as_call(args, kwargs):
|
|
passed = ['self']
|
|
for arg in args[1:]:
|
|
passed.append(repr(arg))
|
|
for key, value in kwargs.items():
|
|
passed.append(f"key={value!r}")
|
|
return "(" + ", ".join(passed) + ")"
|
|
|
|
|
|
def introspected_method(clsname, ctx, name, method):
|
|
def _(*args, **kwargs):
|
|
callstr = f"{clsname}.{name}{as_call(args, kwargs)}"
|
|
print(f"{'| ' * ctx['depth']}Calling {callstr}...")
|
|
ctx["depth"] += 1
|
|
before = perf_counter()
|
|
result = method(*args, **kwargs)
|
|
after = perf_counter()
|
|
ctx["depth"] -= 1
|
|
callstr = f"{clsname}.{name}{as_call(args, kwargs)}"
|
|
print(
|
|
f"{'| ' * ctx['depth']}Returning from {callstr} after {after-before:.2f}s with {result}"
|
|
)
|
|
return result
|
|
|
|
return _
|
|
|
|
|
|
class Introspected(type):
|
|
def __new__(cls, name, bases, ns, **kwds):
|
|
ctx = {"depth": 0}
|
|
for key, value in ns.items():
|
|
if callable(value) and key != "__repr__":
|
|
ns[key] = introspected_method(name, ctx, key, value)
|
|
return super().__new__(cls, name, bases, ns, **kwds)
|
|
|
|
|
|
class Point(metaclass=Introspected):
|
|
def __init__(self, x, y):
|
|
self.x = x
|
|
self.y = y
|
|
|
|
def dist(self, other: Self) -> float:
|
|
return ((other.x - self.x) ** 2 + (other.y - self.y) ** 2) ** 0.5
|
|
|
|
def __repr__(self):
|
|
return f"Point(x={self.x!r}, y={self.y!r})"
|
|
|
|
def modulus(self):
|
|
return self.dist(Point(0, 0))
|
|
|
|
def recursive_call(self, value):
|
|
sleep(0.1)
|
|
if value:
|
|
return self.recursive_call(value - 1)
|
|
else:
|
|
return self.mean()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
p = Point(10, 10)
|
|
print(p.modulus())
|