Reputation: 11
Today I was solving a university problem. There was this class call which I can not change. This was the code:
n = some_class.some_method('arg_1', 'arg_2')
So my written class code is this:
class some_class:
def __init__(self, arg_1, arg_2):
self.some_method(arg_1, arg_2)
def some_method(self, arg_1, arg_2):
self.arg_1 = arg_1
self.arg_2 = arg_2
However, I am getting this error:
AttributeError: 'str' object has no attribute 'arg_1'
Examining a bit, I found that some_method's self is not referring to its own class and thinking it's an argument. So is there any way to init the class inside the method? I can not init the class before this line "n = some_class.some_method('arg_1', 'arg_2')".
I directly implemented the sudo code according to one solution however now I got this error: TypeError: some_method() missing 1 required positional argument: 'arg_2'
class Some_class:
def __init__(self, arg_1, arg_2):
self.some_method(arg_1, arg_2)
@staticmethod
def some_method(self, arg_1, arg_2):
self.arg_1 = arg_1
self.arg_2 = arg_2
def __str__(self):
return 'YES'
n = Some_class.some_method('arg_1', 'arg_2')
Upvotes: 0
Views: 1614
Reputation: 171
There are a few misunderstandings on how your code works.
Classes have two kinds of methods: static and non-static methods.
Non-Static methods: These are the usual methods that you define inside a class. They always have the same first argument: "self"
This "self" argument always refers to the current instance of the class (i.e. They only work on instances).
Static methods: These methods do not have a "self" argument because they do not work on instances. It is like instances do not exist for them.
There are many uses for these kind of methods, but a simple way to look at them is as set of utils stored in a class.
Now, going back to your code.
class Some_class:
def __init__(self, arg_1, arg_2):
self.some_method(arg_1, arg_2)
@staticmethod
def some_method(self, arg_1, arg_2):
self.arg_1 = arg_1
self.arg_2 = arg_2
def __str__(self):
return 'YES'
n = Some_class.some_method('arg_1', 'arg_2')
That fails because "some_method" requires 3 arguments (even though the first one is "self" it does not refers to an instance, because for a static method instances do not exist). This means that you must remove any "self" reference in the arguments or in the body.
So, that's why your code didn't work.
Now, what can you do instead? Use classmethod instead of staticmethod:
class Some_class:
def __init__(self, arg_1, arg_2):
self.arg1 = arg_1
self.arg2 = arg_2
@classmethod
def some_method(self_class, arg_1, arg_2):
return self_class(arg_1, arg_2)
def __str__(self):
return 'YES'
n = Some_class.some_method('arg_1', 'arg_2')
I named "self_class" the first argument of "some_method" in order to make it clear that that first argument is not a reference to an instance (even though you could name it "self" as usual).
The fisrt argument of classmethod methods is a reference to the class.
Upvotes: 0
Reputation: 59302
To make the call like this, some_method
must be static. That's because some_class
is missing the braces ()
which would instantiate an object. Static methods do not have a self
argument and have a @staticmethod
attribute.
If that method shall return an instance, you need to call the constructor some_class()
.
class some_class:
def __init__(self, arg_1, arg_2):
self.arg_1 = arg_1
self.arg_2 = arg_2
@staticmethod
def some_method(arg_1, arg_2):
return some_class(arg_1, arg_2)
some_object = some_class.some_method('arg_1', 'arg_2')
print(some_object)
Style note: classes should be upper case in Python.
Upvotes: 4