Can you set a method attribute in python

I am wondering if setattr can be used to set an attribute for a method inside a class, for example, because when I try to get an error that will be displayed after the code:

class Test: def getString(self, var): setattr(self.getString, "string", var) return self.getString test = Test() test.getString("myString").string 

What are the errors of AttributeError: 'method' object has no attribute 'string' , so I tried this without putting .string and just trying test.getString("myString") The same thing, but I tried it without using a class as shown

 def getString(var): setattr(getString, "string", var) return getString getString("myString").string 

He returned "myString" as I wanted it, so how would I do it in the class and why does it work outside of one, but inside one?

+6
source share
3 answers

type( test.getString ) builtins.method and from the documentation ( methods ),

since the attributes of the method are actually stored in the base function of the object ( meth.__func__ ), the attributes of the installation method on related methods are unresolved. Attempting to set a method attribute will result in an AttributeError .

There are (at least) two possible solutions, depending on what behavior you are looking for. One of them is to set the class method attribute:

 class Test: def getString(self, var): setattr(Test.getString, "string", var) return self.getString test = Test() test.getString("myString").string # > "myString" test2 = Test() test2.getString.string # > this is also "myString" 

and the other is to use function objects:

 class Test: class getStringClass: def __call__ ( self, var ): setattr( self, "string", var ) return self def __init__( self ): self.getString = Test.getStringClass( ) test = Test( ) test.getString( "myString" ).string # > "myString" test2 = Test() test2.getString.string # > this is error, because it does not # have the attribute 'string' yet 
+4
source

Functions are similar to most other objects in which you can freely add attributes to them. Methods, on the other hand ... conceptually they are just functions, but they behave somewhat differently (impicity pass self ) and, therefore, are implemented with a little glue added around the functions.

Each time self.getString is evaluated, a new method object (bound) is created, which is a thin wrapper around the base function (which you can access as Test.getString ). These method objects do not allow you to add attributes, and even if they did, your code would not work because it juggles several different method objects (although they all wrap the same function).

You cannot do this work with related methods. Since you presumably want the string to be bound to the Test object (indirectly by binding to its method), you can make it a Test attribute. You can even create your own object that behaves like a method, but allows attributes (you need to explicitly add it to __init__ ), but honestly, this is probably the best way to separate data and methods. If, on the other hand, you want to attach this attribute to a base function (which would mean that it would be used by all instances of Test ), you can simply set the attribute to Test.getString .

+2
source

So, I found a way, but that’s not how I wanted to do it personally. If someone finds another way to do the following code, feel free to comment on how to do it.

 class Test: def getString(self, string): setattr(self,"newString",self) self.newString.string = string return self.newString 

As I said, it does not seem to me that I did something in this way, but it works for what I need, and if you find another comment for the next.

0
source

Source: https://habr.com/ru/post/959096/


All Articles