Reputation: 3494
This is a similar question but my goal is not performance but readability.
Let's say I have different Behaviours
, and they share a repeated function f1()
.
from abc import ABCMeta, abstractmethod
class Behavior:
__metaclass__ = ABCMeta
@abstractmethod
def run(self):
pass
class Behavior1(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 1.
f1()
class Behavior2(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 2.
f1()
class Behavior3(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 3
f1()
I want f1()
to have access to instance attributes and local variables inside run()
without passing them as arguments.
Probably I can implement that inside Behavior
but I don't have access to localVar
.
from abc import ABCMeta, abstractmethod
class Behavior:
__metaclass__ = ABCMeta
@abstractmethod
def run(self):
pass
def f(self):
print(self.data*localVar)
class Behavior1(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 1.
f1()
self.f()
class Behavior2(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 2.
f1()
self.f()
class Behavior3(Behavior):
def __init__(self, data):
self.data = data
def run(self):
def f1():
print(self.data*localVar)
localVar = 3
f1()
self.f()
Is there any pythonic or OOP way of writting a C-Style macro for f1()
?
Upvotes: 2
Views: 593
Reputation: 160
What you actually want sounds like "access to outer scope variables" which is not global.
If you use python3.x, you should look up the nonlocal keyword.
If you use python2.x, try using a mutable object as a wrapper to your object.
Actually my answer is based on this one.
Upvotes: 0
Reputation: 2979
Macros are not an inherent construct in python since there's no preprocessor like in C++ to use.
As such, anything you do to allow you to only write the code once will have to be done...
Outside of python (i.e. you manually use gcc's preprocessor); or
By using debugging information in python (i.e. you deconstruct the callstack)
The former is a pain in the butt, but is doable.
The latter is also a pain in the butt, but is also doable.
However, since your goal is to increase readability, neither of these options are good because anybody accustomed to python will have absolutely no idea what you're doing. Be very careful when porting language constructs from other languages into python.
If your function needs to modify local variables, then you'll have to write the same lines of code in every place.
If it just needs to use them, I strongly recommend just passing arguments - or rethinking your design and need for many derived classes all doing roughly the same thing in one function (i.e. what if you broke that "function" into several pieces of the function and let derived classes only override the ones they want?).
Upvotes: 2