How to Pass a Local Function to Another Object During Init

Python: passing functions as arguments to initialize the methods of an object. Pythonic or not?

Passing functions to an object is fine. There's nothing wrong with that design.

If you want to turn that function into a bound method, though, you have to be a little careful. If you do something like self.func = lambda x: func(self, x), you create a reference cycle - self has a reference to self.func, and the lambda stored in self.func has a reference to self. Python's garbage collector does detect reference cycles and cleans them up eventually, but that can sometimes take a long time. I've had reference cycles in my code in the past, and those programs often used upwards of 500 MB memory because python would not garbage collect unneeded objects often enough.

The correct solution is to use the weakref module to create a weak reference to self, for example like this:

import weakref

class WeakMethod:
def __init__(self, func, instance):
self.func = func
self.instance_ref = weakref.ref(instance)

self.__wrapped__ = func # this makes things like `inspect.signature` work

def __call__(self, *args, **kwargs):
instance = self.instance_ref()
return self.func(instance, *args, **kwargs)

def __repr__(self):
cls_name = type(self).__name__
return '{}({!r}, {!r})'.format(cls_name, self.func, self.instance_ref())

class FooBar(object):
def __init__(self, func, a):
self.a = a
self.func = WeakMethod(func, self)

f = FooBar(foo1, 7)
print(f.func(3)) # 21

All of the following solutions create a reference cycle and are therefore bad:

  • self.func = MethodType(func, self)
  • self.func = func.__get__(self, type(self))
  • self.func = functools.partial(func, self)

Calling a class function inside of __init__

Call the function in this way:

self.parse_file()

You also need to define your parse_file() function like this:

def parse_file(self):

The parse_file method has to be bound to an object upon calling it (because it's not a static method). This is done by calling the function on an instance of the object, in your case the instance is self.

How to initialize an object from one method to another method within a class?

The reason why this isn't working is scope. A local variable can only be accessed from the block it is declared in. To access it from multiple methods, add a field or pass it to the other method as a parameter.

Field:

class YourClass
{
object yourObject;

void Method1()
{
yourObject = new object();
}

void Method2()
{
int x = yourObject.GetHashCode();
}
}

Parameter:

class YourClass
{
void Method1()
{
Method2(new object());
}

void Method2(object theObject)
{
int x = theObject.GetHashCode();
}
}

How to pass a variable from main function to another function and modify it? (Kotlin)

Kotlin is pass-by-value, so you can't do that directly with primitive types like Int.

The usual approach is to just return a new value instead of modifying what you receive as argument (a functional approach). It makes it clearer from the calling code's perspective:

fun main() {
var num: Int = 5
num = changeNum(num)
}

fun changeNum(num: Int): Int {
val newValue = num + 2
print(newValue)
return newValue
}

If you really want to mutate the variable instead of returning a new value, here are 2 approaches I'm thinking of to do this:

  1. put all the code operating on this value into a class, and make the local variable a property of that class (this is the OO approach)
  2. put this primitive variable into a class, and pass an instance of that class

Option 1 would look like this:

class SomeClass(var num: Int) {

fun changeNum() {
num += 2
print(num)
}
}

fun main() {
val container = SomeClass(5)
container.changeNum()
}

Option 2 would look like this:

class SomeMutableContainer(var num: Int)

fun main() {
val container = SomeMutableContainer(5)
changeNum(container)
}

fun changeNum(container: SomeMutableContainer) {
container.num += 2
print(container.num)
}

Adding a method to an existing object instance

In Python, there is a difference between functions and bound methods.

>>> def foo():
... print "foo"
...
>>> class A:
... def bar( self ):
... print "bar"
...
>>> a = A()
>>> foo
<function foo at 0x00A98D70>
>>> a.bar
<bound method A.bar of <__main__.A instance at 0x00A9BC88>>
>>>

Bound methods have been "bound" (how descriptive) to an instance, and that instance will be passed as the first argument whenever the method is called.

Callables that are attributes of a class (as opposed to an instance) are still unbound, though, so you can modify the class definition whenever you want:

>>> def fooFighters( self ):
... print "fooFighters"
...
>>> A.fooFighters = fooFighters
>>> a2 = A()
>>> a2.fooFighters
<bound method A.fooFighters of <__main__.A instance at 0x00A9BEB8>>
>>> a2.fooFighters()
fooFighters

Previously defined instances are updated as well (as long as they haven't overridden the attribute themselves):

>>> a.fooFighters()
fooFighters

The problem comes when you want to attach a method to a single instance:

>>> def barFighters( self ):
... print "barFighters"
...
>>> a.barFighters = barFighters
>>> a.barFighters()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: barFighters() takes exactly 1 argument (0 given)

The function is not automatically bound when it's attached directly to an instance:

>>> a.barFighters
<function barFighters at 0x00A98EF0>

To bind it, we can use the MethodType function in the types module:

>>> import types
>>> a.barFighters = types.MethodType( barFighters, a )
>>> a.barFighters
<bound method ?.barFighters of <__main__.A instance at 0x00A9BC88>>
>>> a.barFighters()
barFighters

This time other instances of the class have not been affected:

>>> a2.barFighters()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: A instance has no attribute 'barFighters'

More information can be found by reading about descriptors and metaclass programming.

Calling variable defined inside one function from another function

One approach would be to make oneFunction return the word so that you can use oneFunction instead of word in anotherFunction :

def oneFunction(lists):
category = random.choice(list(lists.keys()))
return random.choice(lists[category])


def anotherFunction():
for letter in oneFunction(lists):
print("_", end=" ")

Another approach is making anotherFunction accept word as a parameter which you can pass from the result of calling oneFunction:

def anotherFunction(words):
for letter in words:
print("_", end=" ")
anotherFunction(oneFunction(lists))

And finally, you could define both of your functions in a class, and make word a member:

class Spam:
def oneFunction(self, lists):
category=random.choice(list(lists.keys()))
self.word=random.choice(lists[category])

def anotherFunction(self):
for letter in self.word:
print("_", end=" ")

Once you make a class, you have to instantiate an instance and access the member functions:

s = Spam()
s.oneFunction(lists)
s.anotherFunction()

How to pass values of local variables to another method

you have two solutions:
1: add a parameter to 'PlaceJButtonActionPerformed', which will take as second parameter 'selectedAppointment'
2: or you declare 'selectedAppointment' as a global variable



Related Topics



Leave a reply



Submit