Discussion:
Difference method vs attribut = function
(too old to reply)
Ulrich Goebel
2024-06-28 16:08:54 UTC
Permalink
Hi,

a class can have methods, and it can have attributes, which can hold a function. Both is well known, of course.

My question: Is there any difference?

The code snipped shows that both do what they should do. But __dict__ includes just the method, while dir detects the method and the attribute holding a function. My be that is the only difference?


class MyClass:
def __init__(self):
functionAttribute = None

def method(self):
print("I'm a method")

def function():
print("I'm a function passed to an attribute")

mc = MyClass()
mc.functionAttribute = function

mc.method()
mc.functionAttribute()

print('Dict: ', mc.__dict__) # shows functionAttribute but not method
print('Dir: ', dir(mc)) # shows both functionAttribute and method


By the way: in my usecase I want to pass different functions to different instances of MyClass. It is in the context of a database app where I build Getters for database data and pass one Getter per instance.

Thanks for hints
Ulrich
--
Ulrich Goebel <***@fam-goebel.de>
Peter J. Holzer
2024-06-29 19:53:05 UTC
Permalink
Post by Ulrich Goebel
a class can have methods, and it can have attributes, which can hold a
function. Both is well known, of course.
My question: Is there any difference?
The code snipped shows that both do what they should do. But __dict__
includes just the method,
The other way around: It includes only the attributes, not the methods.
Post by Ulrich Goebel
while dir detects the method and the
attribute holding a function. My be that is the only difference?
functionAttribute = None
print("I'm a method")
print("I'm a function passed to an attribute")
Here is the other main difference: The object is not passed implicitely
to the function. You have no way to access mc here.

You can create a method on the fly with types.MethodType:

import types
mc.functionAttribute = types.MethodType(function, mc)
Post by Ulrich Goebel
By the way: in my usecase I want to pass different functions to
different instances of MyClass. It is in the context of a database app
where I build Getters for database data and pass one Getter per
instance.
Or in this case, since each function is specific to one instance, you
could just use a closure to capture the object. But that might be
confusing to any future maintainers (e.g. yourself in 6 months), if the
method doesn't actually behave like a method.

hp
--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | ***@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
Mats Wichmann
2024-06-29 20:03:13 UTC
Permalink
Post by Ulrich Goebel
By the way: in my usecase I want to pass different functions to different instances of MyClass. It is in the context of a database app where I build Getters for database data and pass one Getter per instance.
If I understood what you're trying to accomplish, you could take a look
here (possibly a bit complex for what you need).

https://refactoring.guru/design-patterns/strategy/python/example
Stefan Ram
2024-06-29 20:48:58 UTC
Permalink
Post by Ulrich Goebel
a class can have methods, and it can have attributes, which
can hold a function. Both is well known, of course.
Methods are attributes too:

Main.py

class c:
def m():
pass

print( *( name for name in dir( c )if not name.startswith( '__' )))

sys.stdout

m

.
Post by Ulrich Goebel
functionAttribute = None
Your local name "functionAttribute" is not an attribute of "MyClass".
Post by Ulrich Goebel
mc = MyClass()
mc.functionAttribute = function
Above, you only add an attribute to "mc", not to "MyClass".
Post by Ulrich Goebel
By the way: in my usecase I want to pass different functions
to different instances of MyClass.
class MyClass:
def __init__( self ):
self.function = None
def accept( self, function ):
self.function = function

mc = MyClass()
mc.accept( print )

mc_1 = MyClass()
mc_1.accept( dir )
Lawrence D'Oliveiro
2024-06-29 22:55:54 UTC
Permalink
Post by Ulrich Goebel
a class can have methods, and it can have attributes, which can hold a
function. Both is well known, of course.
They are indeed:

class A:
def set_x(self, x) :
self.x = x
#end set_x
#end A

class B:
pass
#end class B

def set_x(self, x) :
self.x = x
#end set_x

B.set_x = set_x

AInst = A()
AInst.set_x(9)
print(AInst.x)
BInst = B()
BInst.set_x(4)
print(BInst.x)

Output:

9
4

No fundamental difference between the two ways of attaching a method to a
class.
Thomas Passin
2024-06-29 20:01:49 UTC
Permalink
Post by Ulrich Goebel
Hi,
a class can have methods, and it can have attributes, which can hold a function. Both is well known, of course.
My question: Is there any difference?
The code snipped shows that both do what they should do. But __dict__ includes just the method, while dir detects the method and the attribute holding a function. My be that is the only difference?
functionAttribute = None
print("I'm a method")
print("I'm a function passed to an attribute")
mc = MyClass()
mc.functionAttribute = function
mc.method()
mc.functionAttribute()
print('Dict: ', mc.__dict__) # shows functionAttribute but not method
print('Dir: ', dir(mc)) # shows both functionAttribute and method
By the way: in my usecase I want to pass different functions to different instances of MyClass. It is in the context of a database app where I build Getters for database data and pass one Getter per instance.
Thanks for hints
Ulrich
https://docs.python.org/3/library/functions.html#dir -

object.__dict__¶
A dictionary or other mapping object used to store an object’s
(writable) attributes.

dir(object)
...
With an argument, attempt to return a list of valid attributes for that
object.

"functionAttribute" is a class method, not an instance method. If you
want an instance method:

class MyClass:
def __init__(self):
functionAttribute = None
self.instance_functionAttribute = None

def method(self):
print("I'm a method")
d***@online.de
2024-06-30 17:58:37 UTC
Permalink
Post by Ulrich Goebel
Hi,
a class can have methods, and it can have attributes, which can hold a function. Both is well known, of course.
My question: Is there any difference?
I think you should make the distinction "class versus instance attribute"
rather than "mether versus function".

If you look at the `__dict__` of an instance, you see only the
instance variables (the class's `__dict__` gives you the (most) attributes
of the class).

You can access (most) class attributes via an instance;
if a function is accessed in this way, it becomes (typically) a method.
Loading...