This message was deleted.
# hamilton-help
s
This message was deleted.
s
nice. Any particular reason why via ad_hoc_utils? Is it because you’re in a notebook? Otherwise I’ve thought about the isomorphism of classes with functions:
Copy code
@dataclasses.dataclass(frozen=True)
class AddSome:
    some: str

    def __call__(self, foo: str) -> str:
        return foo + self.some
would be
Copy code
def add_some(some: str, foo: str) -> str:
    return some + foo
But since Hamilton only calls something once — it’s not clear to me the value of an object. If it’s the separation of “constructor arguments” vs “input arguments” it’s not as explicit in the function, but you get the same effect by passing in execution invariant values via “config” during driver construction, and then the rest via “inputs=” when executing. Any particular reason you’re choosing to have a class? Otherwise I think one of the places to change code would be to augment
find_functions
in
graph_utils.py
if it returns a reference to the callable function things “might just work” (might need to figure out how to attach a name 🤔 … )
a
Any particular reason why via ad_hoc_utils? Is it because you’re in a notebook?
No, I’m trying to add many nodes to the dag that do the same thing but a bit differently. So imagine I have many
AddSome
all with a different
some
But it turns out I don’t have that many AddSome, so I wrote different plain
fun add_hello
,
fun add_world
etc. It’s just a bit annoying having to repeat the type hints.
s
e
To add to what @Stefan Krawczyk said, there’s probably a way to hack it in, the assumption is not that deep. but we have a whole bunch of ways to do this type of stuff, that avoids repetition — the whole decorator framework. For the case of
@parameterize
Copy code
from hamilton.function_modifiers import parameterize, value

@parameterize(
    add_foo={"some" : value("foo")},
    add_bar={"some" : value("bar")},
    add_baz={"some" : value("baz")}
)
def add_some(some: str, foo: str) -> str:
    return some + foo

# three nodes: add_foo, add_bar, and add_baz, all dependent on `foo` with `some` fixed
The high-level view of this is that we have a whole algebra of decorators to make it so you don’t have to repeat code if you don’t want to
a
Thanks, parameterize does the trick.
🫡 1
OK so I think with the decorator I don’t think I need any of my callable non sense, I’ll just answer your questions for the sake of it.
Any particular reason you’re choosing to have a class?
I guess defining an object with a
___call___
function is a common way to pass callable in python (basically a more explicit alternative to lambdas or using
functools.partial
). That’s something I use in other API or internally in our codebase.
Otherwise I think one of the places to change code would be to augment
find_functions
in
graph_utils.py
if it returns a reference to the callable function things “might just work” (might need to figure out how to attach a name 🤔 … )
I actually think it will break somewhere done the line.
AddSome('foo').__call__
is a bound method, which is slightly different from a pure/global function in python. For example it will break the dag runtime inspection, because it still shows that
self
is a required argument and it is missing (even though it is still bound to the method).
s
yeah you’re right. Maybe a bit more work than I thought 😅 or creating a function wrapper around it (using a closure) 🤔