ekz1.attr1 и getattr(ekz1, "attr1") равнозначны. Соответственно в функции у вас может написано быть как угодно:
И так:
def foo(ekz1, ekz2):
print(ekz1.attr1, ekz2.attr2)
И так:
def foo(ekz1, ekz2):
print(getattr(ekz1, "attr1"), getattr(ekz2, "attr2"))
Однако, если хотите отследить, что передаются верные объекты в функцию для этого лучше воспользоваться методом hasattr:
class C1:
def __init__(self, value1):
self.attr1 = value1
class C2:
def __init__(self, value2):
self.attr2 = value2
def func(ekz1, ekz2):
if not hasattr(ekz1, "attr1"):
print("{0} has no attr1".format(type(ekz1)))
return
if not hasattr(ekz2, "attr2"):
print("{0} has no attr2".format(type(ekz2)))
return
print(ekz1.attr1, ekz2.attr2)
inst1 = C1(10)
inst2 = C2(11)
func(inst1, inst2)
func(inst1, [1, 2, 3])