Instantiating and Using a Method of a Class Within a Function - python

I'm trying to instantiate a class within a function, then call a method within the class inside the same function, like this:
# Define the class
class myclass:
def __init__(self,string_to_print):
self.string_to_print = string_to_print
def myclass_func(self):
print(self.string_to_print)
# Define the function that utilizes the class
def func(class,func,str)
instance = class(str)
class = class.func()
# Run the function that utilizes the class
func(myclass,myclass_func,str)
But I am getting an error like "'myclass' object is not callable". Why is this? Additionally, I expect my 'class = class.func()' line is wrong; if it is, what is the correct way to call the method from the recently instantiated class?
Edit: fixed mistake in class declaration

You can't use method names as global variables. If you want to call a method dynamically, pass its name as a string and use the getattr() function.
# Define the class
class myclass:
def __init__(self,string_to_print):
self.string_to_print = string_to_print
def myclass_func(self):
print(self.string_to_print)
# Define the function that utilizes the class
def func(class,func,str)
instance = class(str)
return getattr(instance, func)()
# Run the function that utilizes the class
func(myclass,'myclass_func',str)

Define your class using the class keyword rather than def.
Create an instance of the class.
Define a function that will try to execute the function given by its name.
class myclass:
def __init__(self,string_to_print):
self.string_to_print = string_to_print
def myclass_func(self):
print(self.string_to_print)
myclass_instance = myclass('Hello world')
def execute_function(instance, function):
getattr(instance, function)()
execute_function(myclass_instance, 'myclass_func')
Output:
Hello world

Related

Is there a way to call specific classes based on a variable?

I want a program to call a specific class based on a parameter/variable value. However, I don't want to use any clunky if-statements. My first thought was to use the globals() function, but I couldn't get it to work. Here's an example:
class SomeClass:
def __init__():
print("Hello, world!")
class OtherClass:
def runClass(className):
# Call class based on variable className
The reason I want to do this is because there is a wide variety of classes may need to be called, and so just piling up if-statements in my code won't do it. Any help would be greatly appreciated. Thanks!
Here's how you can call a class via globals
class SomeClass:
def __init__(self):
print("Hello, world!")
def __call__(self):
return "SomeClass called"
class OtherClass:
def runClass(self, className):
globals()[className]()()
o = OtherClass()
result = o.runClass("SomeClass")
print(result)
Notice, I am instantiating and then calling it via the __call__ special method, which is the closest match to your description I could think of.
Use a dict.
name_to_class = dict(some=SomeClass,
other=OtherClass)
def factory(name):
klass = name_to_class(name)
return klass()
some_obj = factory("some")
other_obj = factory("other")
One way to solve this problem is to use a dictionary to map the values of the variable className to the corresponding class.
Try this exemple :
class SomeClass:
def init(self):
print("Hello, world!")
class OtherClass:
def init(self):
print("Goodbye, world!")
classNameToClass = {
"SomeClass": SomeClass,
"OtherClass": OtherClass
}
def runClass(className):
# Call class based on variable className
cls = classNameToClass[className]
return cls()
runClass("SomeClass") # prints "Hello, world!"
runClass("OtherClass") # prints "Goodbye, world!"
Here, the dictionary classNameToClass maps the string names of the classes (e.g. "SomeClass") to the corresponding class objects (e.g. SomeClass). Then, in the runClass function, we look up the class object using the value of the className variable, and call it to create an instance of the class.
I've found an answer. The parameter that governs the called class can just be assigned elsewhere. At first, I thought it would need some complex function, but in reality, I guess the question didn't give enough details. The class itself only uses items from whatever object is given. So, instead of having to dynamically call a class, it's as simple as:
class SomeClass:
def printHelloWorld():
print("Hello, world!")
class OtherClass:
def __init__(self, usingClass):
self.object = usingClass
def doThis():
usingClass.printHelloWorld()
x = OtherClass(SomeClass())
x.doThis()
It's on me for not giving enough information. Thank you all for your help.

Cross Class Subclass use

I am experimenting with python object orientated programming. Of course I learned about inheritence and so on, but this question is very specific and I couldn't find the answer anywhere yet.
Let's say we have a class class mainClass:. In this class there is a function def func(self):. And within this function func() I want to use two custom classes. Can I and how can I use the first custom class within the second one? (Here's a example)
class custom1:
def func1(self):
#do something
class custom2:
def func2(self):
#call function func1 from class custom1 without creating another instance
class mainClass:
def func(self):
obj1 = custom1()
obj2 = custom2()
obj2.func2()
Like I said I don't want to create a second instance of custom1 within custom2. Only the one in mainClass.
Thanks for your answers :)
what about passing it via the constructor of the first class?
class custom1:
def func1(self):
#do something
class custom2:
def __init__(self, obj1):
self._obj1 = obj1
def func2(self):
self._obj1.func1()
class mainClass:
def func(self):
obj1 = custom1()
obj2 = custom2(obj1)
obj2.func2()

AttributeError resulting from function defined in class definition

I am trying to learn how to define classes in Python, starting by creating a very basic example:
class CustomClass:
def print_class(self):
print(self)
CustomClass = 'Hello World'
CustomClass.print_class()
Yet when I run this, I get the error:
AttributeError: 'str' object has no attribute 'print_class'
I don't want to try to access or define some attribute of this class. I want to run the function defined when the class is defined. Could someone point out what I am doing wrong?
what do you wanted to do with this statement: CustomClass = 'Hello World'
if you want to instantiate an object of that class you need to do something like this:
name_of_object = CustomClass() # create an object
name_of_object.print_class() # this will call the method in that class
There is no self in a stand-alone function. If you define a class and instantiate it, self will refer to that object. You’re trying to use an attribute of a class object in the context of no object.
Example:
class Test(object):
def __init__(self, text):
self.text = text
def print_me(self):
print(self.text)
o = Test(‘Hello world’)
o.print_me()
Try that.
Fixed Code:
class CustomClass:
def print_class(self):
print(self)
myClass = CustomClass()
myClass.print_class()

Static initializer for Python classes

I'm looking for an equivalent to the static { ... } block in Java that can be used in Python classes. Specifically, I want to be able to access static resources like the arguments of the class constructor and store them in a field of the class, like so:
class A:
constructor_args = A.__init__.__code__.co_varnames
def __init__(self, foo=0, bar=1):
...
This example doesn't work, because class A is not yet initialized when I call A.__init__.__code__.co_varnames.
My current workaround is to alter the static field after the class has been created like so:
class A:
constructor_args = ...
def __init__(self, foo=0, bar=1):
...
constructor_args = A.__init__.__code__.co_varnames
But this solution is rather ugly because I change a static field of a class outside of the class context and if the class contains a lot of code, it's easy to miss out on what is going on here.
So basically I need a way to call a function right after the class has been initialized, and I want to define this function inside of the class.
You will have to at least define the __init__ method first, but you can access its properties immediately after:
class Foo:
def __init__(self, bar, baz):
pass
constructor_args = __init__.__code__.co_varnames
Inside the class block code executes inside its own namespace, so __init__ is directly accessible as __init__.
Here is a simple approach that postpones execution of code that needs the finished class by moving it inside a function defined inside the class body. To have the function called and deleted after use we define a simple decorator:
import inspect
def finalizing(cls):
cls.__finalize__(cls)
del cls.__finalize__
return cls
#finalizing
class example:
def __finalize__(me):
me.constructor_args = list(inspect.signature(me.__init__).parameters)
def __init__(self, x):
pass
example.constructor_args
# ['self', 'x']
You could use a class decorator:
def store_constructor_args(cls):
cls.constructor_args = cls.__init__.__code__.co_varnames
return cls
#store_constructor_args
class A:
def __init__(self, foo=0, bar=1):
x = 10
print(A.constructor_args)
# ('self', 'foo', 'bar', 'x')
#store_constructor_args
class A:
is equivalent to
class A:
...
A = store_constructor_args(A)

Referencing a method while setting class attributes

class Something(object):
our_random = Something.random_thing
#staticmethod
def random_thing():
return 4
Of course, this doesn't work, becauese Something doesn't exist when I attempt to call its method. Nor does this:
class Something(object):
our_random = random_thing
#staticmethod
def random_thing():
return 4
I've "solved" this by Just placing random_thing()'s definition above the class, but I find this messy.
Call it in the .__init__() initializer then:
class Something(object):
def __init__(self):
self.our_random = Something.random_thing()
or call the static method after you defined it, but are still defining the class; because it is a static method, you'd have to access it through the __func__ attribute:
class Something(object):
#staticmethod
def random_thing():
return 4
our_random = random_thing.__func__()
If you didn't mean to call it, just create a copy of the method with a different name, just do so after you defined it:
class Something(object):
#staticmethod
def random_thing():
return 4
our_random = random_thing # our_random as an alias for random_thing
The class body is executed as a function, with the local namespace of the function then forming the class attributes. So, like a function, if you want to refer to other objects you need to make sure they are defined first.
class Something(object):
#staticmethod
def random_thing():
return 4
our_random = random_thing
Class definitions create a namespace, so you can refer to other names (class attributes) within the class body without needing to access them through the class.

Categories

Resources