I have two classes, and a "use" class function that preforms multiple actions using the various attributes as the inputs so that i can just call the one function and get different results based on which class object is referenced. Where I am getting stuck is that I want to have part of the use function check the 'effect' attribute and call the function found there. currently, function named in effect is called when the object c is defined, and everything i have tried within the use function has no effect or returns 'none' since i dont have a return statement in the add and sub functions. Provided simplified example code below. C has 9 attributes, and 10 different class functions i would want to use in the effect spot.I plan on having 50 different c objects, so not having to write out specific functions for each one would be spectacular.
in this example, the print(p.h) at the end returns 101, showing that designing the c object calls the add function i put in the attribute
M= []
class P:
def __init__(p, h, s):
p.h= h
p.s=s
class C:
def __init__(y, name, d, f effect,):
y.name= name
y.effect= effect
y.d= d
y.f= f
def use(c):
M.append(c)
p.h -= p. y.d
p.s = y.f
effect
def add(c, x):
p.h = x
def sub(c, x):
p.h -=x
p= P(100)
c= C('test1', add(1), 1)
print(p.h)
I have tried the add and sub functions as both class and standalone which didnt seem to make a different, calling y.effect as though it were a function which just returns 'none' as mentioned, and adding the property decorator which threw an error probably because i dont quite understand what that is supposed to do yet.
CodePudding user response:
When accessing methods of classes C
and P
, you will only be able to access them from the class namespace. C.add
will work, but add
will not.
Furthermore if you call c.add(4)
it will be the same thing as calling C.add(c, 4)
because it will implicitly pass the instance c
into the class (C
) method C.add
. You cannot call add(1)
or c.add(1)
before your instance c
is initialized by the __init__
method.
Typically when writing python, it is most clear to always name the first argument to your class method self
to make it clear that self
refers to the instance and that it will automatically get passed into the function.
Furthermore, because you do not instantiate p
until after you define your class C
, you won't be able to access p
from inside your C class unless you pass p
into the function or save it as an attribute of c
.
Not totally sure what you are going for here but I made some modifications which might help.
#!/usr/bin/env python
M = []
class P:
def __init__(self, h, s):
# self refers to your instance of p
self.h = h
self.s = s
class C:
def __init__(self, name, p, d, f, effect):
# self refers to your instance of c
self.p = p # save an instance of p as an attribute of your instance of c
self.name = name
self.effect = effect
self.d = d
self.f = f
def use(self):
M.append(self)
self.p.h -= self.d
self.p.s = self.f
return self.effect
def add(self, x):
# self refers to your instance of c and gets implicitly passed in as the first argument
# when c.add(2) is called
self.p.h = x
def sub(self, x):
self.p.h -= x
p = P(100, 50)
c = C('test1', p, d=2, f=1, effect="a")
c.add(1)
print(p.h)
<script src="https://modularizer.github.io/pyprez/pyprez.min.js"></script>
CodePudding user response:
This code isn't runnable as-is, so there may be other problems with your real code that aren't possible to discern from this example, but when you say:
function named in effect is called when the object c is defined
that's happening not because of what's inside your C
class, but the line where you construct your C
:
c= C('test1', add(1), 1)
The expression add(1)
isn't passing the add
function, it's calling the add
function and passing its result. To pass a function as an argument, just pass the function itself without the ()
:
c = C('test1', add, 1)
Note that in the code you provided there is no function called add
in the current scope, and your C.use
does not call effect
, which is a different problem.