Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have a class in which I collect data to list with the help of wide range of methods (say 23). Every method uses list and could modify it. My question is how can I call (in class, respectively) all methods of class in more generally accepted way?
class Example(object):
def __init__(self):
self.lst = []
def multiply(self):
for i in xrange(10):
self.lst.append(i**2)
def get_list(self):
return self.lst
# Calling:
ex = Example()
ex.multiply
print ex.get_list
# What I want is call multiply method inside class and just do this
print ex.get_list
Example class illustrates my idea. I know that it is possible to solve my problem through iterating with Example.__dict__values(), calling all methods in one class's method or with inspect module, but I am not sure that there are not more pure-Pythonic ways.
UPDATE:
All I want is to collect configuration data for yapf formatter.
The main problem is how to call all methods in class - I don't want to implement all configuration analysis of input file in one method. OOP and patterns is my guide.
UPDATE 2:
Answer for Jared Goguen. I want to create class to collect data to dictionary and send it to CreateStyleFromConfig method.
And when it will done, I want just to get get_style method from class without calling all methods inside it:
config = ConfData() # Class which collects all configurations from file
config.get_style()
ConfData class contains methods with specific for data name. For example:
def align_closing_bracket_with_visual_indent(self):
# Do some work..
pass
So, I guess there are two potential solution to this, but I don't really like either of them. I think you might be approaching the problem the wrong way.
You could use an external decorator track and a class variable tracker to keep track of which methods you want to call.
def track(tracker):
def wrapper(func):
tracker.append(func)
return func
return wrapper
class Example:
tracker = []
#track(tracker)
def method_a(self):
return [('key_a1', 'val_a1'), ('key_a2', 'val_a2')]
#track(tracker)
def method_b(self):
return [('key_b1', 'val_b1'), ('key_b2', 'val_b2')]
def collect_data(self):
return dict(tup for method in self.tracker for tup in method(self))
print Example().collect_data()
# {'key_b1': 'val_b1', 'key_b2': 'val_b2', 'key_a1': 'val_a1', 'key_a2': 'val_a2'}
With this approach, you can have utility methods in your class that you don't want to call.
Another approach would be to inspect the directory of your class and logically determine which methods you want to call.
from inspect import ismethod
class Example:
def method_a(self):
return [('key_a1', 'val_a1'), ('key_a2', 'val_a2')]
def method_b(self):
return [('key_b1', 'val_b1'), ('key_b2', 'val_b2')]
def collect_data(self):
data = {}
for attr in dir(self):
if not attr.startswith('_') and attr != 'collect_data':
possible_method = getattr(self, attr)
if ismethod(possible_method):
data.update(possible_method())
return data
This approach is similar to the one mentioned in your post (i.e. iterating over __dict__) and is weak because any instance methods that you don't want to call need to start with '_'. You can adapt this approach to use some other naming convention, but it might not be readable to anyone else.
Either of these methods could implement the collect_data portion as a super-class, allowing you to create minimal sub-classes. This doesn't really help much with the first approach.
class MethodTracker(object):
def collect_data(self):
return dict(tup for method in self.tracker for tup in method(self))
class Example(MethodTracker):
tracker = []
#track(tracker)
def method_a(self):
return [('key_a1', 'val_a1'), ('key_a2', 'val_a2')]
#track(tracker)
def method_b(self):
return [('key_b1', 'val_b1'), ('key_b2', 'val_b2')]
With the second approach, the resulting sub-class is minimal. Also, you can do a little reflection to allow the super-class to have utility methods that don't start with '_'.
from inspect import ismethod
class MethodTracker(object):
def collect_data(self):
data = {}
for attr in dir(self):
if not attr.startswith('_') and not hasattr(MethodTracker, attr):
possible_method = getattr(self, attr)
if ismethod(possible_method):
data.update(possible_method())
return data
def decoy_method(self):
return 'This is not added to data.'
class Example(MethodTracker):
def method_a(self):
return [('key_a1', 'val_a1'), ('key_a2', 'val_a2')]
def method_b(self):
return [('key_b1', 'val_b1'), ('key_b2', 'val_b2')]
Related
I have a python file which can be resumed as follow :
from external_libs import save
class FakeClass1(MotherFakeClass1):
#property
def field(self):
if self.settings['save_parameter_booelan']:#settings come from the mother class but irelevant
import FakeClass2.save as save
# I want to override the save method by the one defined in the FakeClass2
return BehaviorModifierField(super(FakClass1, self).field) #The behavior Modifier decorate the new field but it's irelevant of what it does.
return super(FakClass1, self).field
def fakeMethod(self, boolean_val):
save('blabla')
class FakeClass2:
#staticmethod
def save(test):
#irrelevant core of the method
The idea is here but I struggle to find the right to do this.
I think I could do it more properly if I could move the FakeClass2 in another file but I don't want to.
Do you have a better idea ?
A staticmethod is not the right choice, as its invoked via Class.method. Your save is not used like that. And even if it were, it's on FakeClass, not FakeClass2.
If you want to invoke a different save depending on the class, just add a save METHOD (not function!) and use the function of choice. E.g.
from library import standard_save
class A:
def work(self):
self.save()
def save(self):
standard_save()
class B(A):
def save(self):
do_something_else()
Don't pass a boolean; pass the function to be used.
import external_libs
class FakeClass1:
def __init__(self, save_function=external_libs.save):
self.save = save_function
# Does this method do anything other than change the save function
# to use? If not, it can be eliminated.
def field(self):
# Use self.save as the function to save things
def fakeMethod(self, boolean_val):
self.save('blabla')
class FakeClass2:
#staticmethod
def save(test):
#irrelevant core of the method
instance1 = FakeClass1(FakeClass2.save)
instance2 = FakeClass1() # Default of external_libs.save
I think you are overcomplicating things.
Having a boolean value determining the behaviour of the save method means that the save method behaves differently depending on the instance of the class, according to the boolean value of the instance.
If this is what you want, this is the simplest way I can think.
class FakeClass1(MotherFakeClass1):
def __init__(self):
#your __init__ here
def save(self):
if self.settings['save_parameter_booelan']:
FakeClass2.save()
#or whatwever method you want to use in this case,
#even if is not this class method or another class method
else:
raise NotImplementedError
#or whatever code should be executed by save
#when save_parameter_boolean is false
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm working on a project where being able to discover the order of declaration of functions within a class would be quite useful. Basically, I'd like to be able to guarantee that all functions within a class are executed in the order they are declared.
The end result is a web page in which the order of the output of the functions matches the order in which the functions are declared. The class will inherit from a generic base class that defines it as a web page. The web application will dynamically load the .py file.
class Register(object):
def __init__(self):
self._funcs = []
def __call__(self, func):
self._funcs.append(func)
return func
class MyClass(object):
_register = Register()
#_register
def method(self, whatever):
yadda()
# etc
from types import MethodType, FunctionType
methodtypes = set((MethodType, FunctionType, classmethod, staticmethod))
def methods_in_order(cls):
"Given a class or instance, return its methods in the order they were defined."
methodnames = (n for n in dir(cls) if type(getattr(cls, n)) in methodtypes)
return sorted((getattr(cls, n) for n in methodnames),
key=lambda f: getattr(f, "__func__", f).func_code.co_firstlineno)
Usage:
class Foo(object):
def a(): pass
def b(): pass
def c(): pass
print methods_in_order(Foo)
[<unbound method Foo.a>, <unbound method Foo.b>, <unbound method Foo.c>]
Also works on an instance:
print methods_in_order(Foo())
If any inherited methods were defined in a different source file, the ordering may not be consistent (since the sort relies upon each method's line number in its own source file). This could be rectified by manually walking the class's method resolution order. This would be a fair bit more complicated so I won't take a shot here.
Or if you want only the ones directly defined on the class, which seems like it might be useful for your described application, try:
from types import MethodType, FunctionType
methodtypes = set((MethodType, FunctionType, classmethod, staticmethod))
def methods_in_order(cls):
"Given a class or instance, return its methods in the order they were defined."
methodnames = (n for n in (cls.__dict__ if type(cls) is type else type(cls).__dict__)
if type(getattr(cls, n)) in methodtypes)
return sorted((getattr(cls, n) for n in methodnames),
key=lambda f: getattr(f, "__func__", f).func_code.co_firstlineno)
This assumes a new-style class.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have this code:
class SomeClass:
#classmethod
def func1(cls,arg1):
#---Do Something---
#classmethod
def func2(cls,arg1):
#---Do Something---
# A 'function map' that has function name as its keys and the above function
# objects as values
func_map={'func1':func1,'func2':func2}
#classmethod
def func3(cls,arg1):
# following is a dict(created by reading a config file) that
# contains func names as keys and boolean as values that tells
# the program whether or not to run that function
global funcList
for func in funcList:
if funcList[func]==True:
cls.func_map[func](arg1) #TROUBLING PART!!!
if _name__='main'
SomeClass.func3('Argumentus-Primus')
When I run this I keep getting the error:
Exception TypeError: "'classmethod' object is not callable"
I am unable to figure out what is wrong with this and would appreciate your help.
You can't create references to classmethods until the class has been defined. You'll have to move it out of the class definition. However using a global function map to decide what gets run is really awkward. If you described what you are trying to do with this, we could probably suggest a better solution.
class SomeClass(object):
#classmethod
def func1(cls, arg1):
print("Called func1({})".format(arg1))
#classmethod
def func2(cls, arg1):
print("Call func2({})".format(arg1))
#classmethod
def func3(cls, arg1):
for fnName,do in funcList.iteritems():
if do:
try:
cls.func_map[fnName](arg1)
except KeyError:
print("Don't know function '{}'".format(fnName))
# can't create function map until class has been created
SomeClass.func_map = {
'func1': SomeClass.func1,
'func2': SomeClass.func2
}
if __name__=='__main__':
funcList = {'func1':True, 'func2':False}
SomeClass.func3('Argumentus-Primus')
I discovered something tonight that will be helpful here: We can unwrap magic staticmethod and classmethod objects via: getattr(func, '__func__')
How did I find this information? Using JetBrains' PyCharm (I don't know about other Python IDEs), I viewed the source code for #staticmethod and #classmethod. Both classes define the attribute __func__.
"The rest is left as an exercise for the reader."
All other answers suggest to add some code outside the class SomeClass definition. It may be ok in some cases, but in my case it was very inconvenient. I really wanted to keep the func_map inside the class.
I suggest the following approach. Use not a class variable, but one more classmethod:
class SomeClass:
# ...
#classmethod
def get_func_map(cls):
return {'func1': cls.func1, 'func2': cls.func2}
#classmethod
def func3(cls, arg1):
# .....
cls.get_func_map()[func_name](arg1)
Of course you should modify this code so that a new dictionary not be constructed each time you call the get_func_map method. It's easy, I did not do myself it to keep the example small and clear.
Tested on python 3.6
Add self as an argument for each method within the class.
Also
if _name__='main'
SomeClass.func3('Argumentus-Primus')
should look like this:
if __name__=='__main__':
SomeClass.func3('Argumentus-Primus')
and should not be within the body of the class.
You may need to try a static method.
#staticmethod
def function():...
Static methods do not pass the class as an implicit first argument.
Here's a bad way to do it:
def func3(cls,arg1):
global funcList
for func in funcList:
if funcList[func]==True:
eval(f'SomeClass.{func}')(arg1)
Only works if func is the name of the function. That being said, do not use this method, because you're taking user input. It would be very easy to inject nasty code in the call. That being said, this does work.
This question already has answers here:
Making functions non override-able
(6 answers)
Closed 3 years ago.
Is there any way I can prevent a child class from overriding a method in the base class?
My guess is that there is not, but I'm coming from the .NET world, and I'm trying to make my API as robust as possible, so any input is greatly appreciated.
class Parent:
def do_something(self):
'''This is where some seriously important stuff goes on'''
pass
class Child(Parent):
def do_something(self):
'''This should not be allowed.'''
pass
Is it possible to enforce this? I know the compiler won't help, so maybe by means of some runtime check? Or is it just not a pythonic way of going about things?
You are right: what you are attempting is contrary to Python's structure and its culture.
Document your API, and educate your users how to use it. It's their program, so if they still want to override your function, who are you to prevent them?
If a API lets you provide subclasses of a certain class and calls your (legally) overridden methods, but also other API methods of that class with simple names like "add", accidentally overriding those methods could lead to hard-to-track-down bugs. It's better to at least warn the user.
The cases where a user wants/needs to override a method that will completely break the API is practically zero. The cases where a user accidentally overrides something that he shouldn't and needs hours to find the culprit are far more frequent. Debugging faulty behaviour caused by this can be cumbersome.
This is how I use to warn or protect attributes from being accidentally overridden:
def protect(*protected):
"""Returns a metaclass that protects all attributes given as strings"""
class Protect(type):
has_base = False
def __new__(meta, name, bases, attrs):
if meta.has_base:
for attribute in attrs:
if attribute in protected:
raise AttributeError('Overriding of attribute "%s" not allowed.'%attribute)
meta.has_base = True
klass = super().__new__(meta, name, bases, attrs)
return klass
return Protect
You can use it like this:
class Parent(metaclass=protect("do_something", "do_something_else")):
def do_something(self):
'''This is where some seriously important stuff goes on'''
pass
class Child(Parent):
def do_something(self):
'''This will raise an error during class creation.'''
pass
uzumaki already provided one metaclass as a possible solution to the question asked above, but here is another with example usage. Following an attempt to create a Child class, another way of making it difficult to override methods is shown. Putting two underscores before but not after an attribute name will automatically cause name mangling to be invoked. See this answer to another question for an easy-to-use way of accessing this ability manually.
#! /usr/bin/env python3
class Access(type):
__SENTINEL = object()
def __new__(mcs, name, bases, class_dict):
private = {key
for base in bases
for key, value in vars(base).items()
if callable(value) and mcs.__is_final(value)}
if any(key in private for key in class_dict):
raise RuntimeError('certain methods may not be overridden')
return super().__new__(mcs, name, bases, class_dict)
#classmethod
def __is_final(mcs, method):
try:
return method.__final is mcs.__SENTINEL
except AttributeError:
return False
#classmethod
def final(mcs, method):
method.__final = mcs.__SENTINEL
return method
class Parent(metaclass=Access):
#Access.final
def do_something(self):
"""This is where some seriously important stuff goes on."""
pass
try:
class Child(Parent):
def do_something(self):
"""This should not be allowed."""
pass
except RuntimeError:
print('Child cannot be created.')
class AnotherParent:
def __do_something(self):
print('Some seriously important stuff is going on.')
def do_parent_thing(self):
self.__do_something()
class AnotherChild(AnotherParent):
def __do_something(self):
print('This is allowed.')
def do_child_thing(self):
self.__do_something()
example = AnotherChild()
example.do_parent_thing()
example.do_child_thing()
Goal: Make it possible to decorate class methods. When a class method gets decorated, it gets stored in a dictionary so that other class methods can reference it by a string name.
Motivation: I want to implement the equivalent of ASP.Net's WebMethods. I am building this on top of google app engine, but that does not affect the point of difficulty that I am having.
How it Would look if it worked:
class UsefulClass(WebmethodBaseClass):
def someMethod(self, blah):
print(blah)
#webmethod
def webby(self, blah):
print(blah)
# the implementation of this class could be completely different, it does not matter
# the only important thing is having access to the web methods defined in sub classes
class WebmethodBaseClass():
def post(self, methodName):
webmethods[methodName]("kapow")
...
a = UsefulClass()
a.post("someMethod") # should error
a.post("webby") # prints "kapow"
There could be other ways to go about this. I am very open to suggestions
This is unnecessary. Just use getattr:
class WebmethodBaseClass():
def post(self, methodName):
getattr(self, methodName)("kapow")
The only caveat is that you have to make sure that only methods intended for use as webmethods can be used thus. The simplest solution, IMO, is to adopt the convention that non-webmethods start with an underscore and have the post method refuse to service such names.
If you really want to use decorators, try this:
def webmethod(f):
f.is_webmethod = True
return f
and get post to check for the existence of the is_webmethod attribute before calling the method.
This would seem to be the simplest approach to meet your specs as stated:
webmethods = {}
def webmethod(f):
webmethods[f.__name__] = f
return f
and, in WebmethodBaseClass,
def post(self, methodName):
webmethods[methodName](self, "kapow")
I suspect you want something different (e.g., separate namespaces for different subclasses vs a single global webmethods dictionary...?), but it's hard to guess without more info exactly how your desires differ from your specs -- so maybe you can tell us how this simplistic approach fails to achieve some of your desiderata, so it can be enriched according to what you actually want.
class UsefulClass(WebmethodBaseClass):
def someMethod(self, blah):
print(blah)
#webmethod
def webby(self, blah):
print(blah)
class WebmethodBaseClass():
def post(self, methodName):
method = getattr(self, methodName)
if method.webmethod:
method("kapow")
...
def webmethod(f):
f.webmethod = True
return f
a = UsefulClass()
a.post("someMethod") # should error
a.post("webby") # prints "kapow"