Apologies upfront if this is a dupe; I search for "_curried python" and got 14 results, and then simply _curried" and that only bumped up to 33 results, and none seemed to help out...
The problem: I came across what I originally thought was a typo in our codebase today, here is the suspect:
student.recalculate_gpa()
Now, I suspect it to be a typo because student is an instance of a Student class that has no recalculate_gpa method. However, it does have a calculate_gpa method:
class Student(User):
...
def calculate_gpa(self):
# some calculations...
(Where User is the standard django user class.) But, the code wasn't erroring, which made no sense to me. So I did an inspect and found this:
... (a bunch of methods)
('calculate_gpa', <unbound method Student.calculate_gpa>),
... (some more methods)
('recalculate_gpa', <unbound method Student._curried>),
Strange, recalculate_gpa is in fact a method. But where on earth does it come from? I grep'd for "_curried" in our codebase and found nothing, so this must be some Django-related behavior. Certainly I would expect that somewhere in our project we've described how dynamically named functions are formed since recalculate seems like a plausible derivative of calculate, but I honestly have no idea where to start looking.
Thus, my question: how are curried methods like the one above generated, and where should I start looking to discover how our own codebase is curry-ing?
Thanks a ton in advance!
a curried method is when you partially call a method in advance of actually calling it
for example
from functools import partial
from itertools import count
def my_pow(x,y):
return x**y
curried_pow2n = partial(my_pow,x=2)
for i in count(0): #print the 2**i
print curried_pow2n(i)
you could also easily implement it with lambda
curried_pow2n = lambda x:return my_pow(2,x)
although Im not sure this has anything to do with your actual question ...
django also provides a curry method that is pretty similar to functools.partial
from django.utils.functional import curry
lols = {'lols':'lols'}
formset = modelformset_factory(MyModel, form=myForm, extra=0)
formset.form = staticmethod(curry(MyForm, lols=lols))
(from https://stackoverflow.com/a/25915489/541038)
so you may want to look for Student.recalculate_gpa =
or perhaps in the Student.__init__ method for self.recalculate_gpa =
you likely would not find it looking for def recalculate_gpa
Related
I am pretty new to Python and am tackling OOP. I am a bit confused as to when to use calls to methods and classes. The sample code below outputs the average, however I am curious as to when you would use calling from the Class vs methods from a real-world perspective. I'm pretty sure this is just something that I may have yet to tackle, but it's just been a bit of a confusion as to when I would use one over the other.
class Student:
def __init__(self, new_name, new_grades):
self.name = new_name
self.grades = new_grades
def average(self):
return sum(self.grades) / len(self.grades)
student_one = Student('Test User', [70, 88, 90, 99])
# object.method()
print(student_one.average())
# Class.method(object)
print(Student.average(student_one))
In your example, there is no difference. Use the first way. The second way makes it appear as though you need to use "the back door" for some reason, for example if student_one was not actually a Student instance but you wanted to specifically call the average method of the Student class.
If an experienced Python developer were to read your code, seeing Student.average(student_one) may make them pause for a moment and wonder why the author wants to use the unbound average here. It would be an unusual style, and perhaps could imply that there may be something more subtle happening than there really was - a stumbling block.
For what's going on behind the scenes, the first way uses a bound method and the second way just uses a normal function.
>>> Student.average
<function __main__.Student.average(self)>
>>> student_one.average
<bound method Student.average of <__main__.Student object at 0xcafef00d>>
A bound method is just a function which is bound to an instance, via descriptor protocol*, and the instance ("self") is passed as the first positional argument implicitly:
>>> student_one.average.__self__ is student_one
True
>>> student_one.average.__func__ is Student.average
True
By using the function on the class and passing in the instance explicitly, you essentially do the same thing as an invocation of the descriptor does automatically.
For a deeper understanding of what a method is, there's detailed documentation of this binding process in the docs here.
* Just a fancy way of saying via the "." i.e. the dotted attribute access
This seems to be a common error in Python, and I've found many instances of people asking about similar but spent the last (long amount of time) trying those solutions where they seemed applicable and have had no luck, so resorting to asking to find out what I'm missing.
I'm receiving AttributeError: WebHandler instance has no attribute 'search_str'
It seems to be this one particular method, any time I call any of the class variables set in ___init___ from this method I receive this error. I've extracted it to a test file as a simple function rather than a class method and it works fine, and I've tried re-indenting everything a few times to make sure it wasn't that, so I'm at a loss on this.
I'm using Python 2.7 and TextWrangler if either of these are helpful (TextWrangler hasn't given me any problems in 3 years like this, but figured anything should be included)
import requests
import re
class WebHandler():
def ___init___(self):
self.urllist = []
self.search_str = re.compile(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_#.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', re.I|re.M)
def set_urls(self, test, data):
for line in test[11:]:
if (("even" in line) or ("odd" in line)):
match = re.search(self.search_str, line)
self.urllist.append(match.group(0))
Another thing I tried, if I copy the attributes from ___init___ and simply make them local to set_urls() and call them without self that way it works properly and doesn't throw any errors, which is confusing me even more.
No idea what I'm missing. Thanks!
Your init function has three underscores:
def ___init___(self):
It should have only two:
def __init__(self):
As it is written now, it is not being called when you create a new object.
This that you have:
def ___init___(self):
Is not the same as this that gets called when an object is instantiated:
def __init__(self):
The difference is that you have three underscores on either side of init, while two are required.
First, if you guys think the way I'm trying to do things is not Pythonic, feel free to offer alternative suggestions.
I have an object whose functionality needs to change based on outside events. What I've been doing originally is create a new object that inherits from original (let's call it OrigObject()) and overwrites the methods that change (let's call the new object NewObject()). Then I modified both constructors such that they can take in a complete object of the other type to fill in its own values based on the passed in object. Then when I'd need to change functionality, I'd just execute myObject = NewObject(myObject).
I'm starting to see several problems with that approach now. First of all, other places that reference the object need to be updated to reference the new type as well (the above statement, for example, would only update the local myObject variable). But that's not hard to update, only annoying part is remembering to update it in other places each time I change the object in order to prevent weird program behavior.
Second, I'm noticing scenarios where I need a single method from NewObject(), but the other methods from OrigObject(), and I need to be able to switch the functionality on the fly. It doesn't seem like the best solution anymore to be using inheritance, where I'd need to make M*N different classes (where M is the number of methods the class has that can change, and N is the number of variations for each method) that inherit from OrigObject().
I was thinking of using attribute remapping instead, but I seem to be running into issues with it. For example, say I have something like this:
def hybrid_type2(someobj, a):
#do something else
...
class OrigObject(object):
...
def hybrid_fun(self, a):
#do something
...
def switch(type):
if type == 1:
self.hybrid_fun = OrigObject.hybrid_fun
else:
self.fybrid_fun = hybrid_type2
Problem is, after doing this and trying to call the new hybrid_fun after switching it, I get an error saying that hybrid_type2() takes exactly 2 arguments, but I'm passing it one. The object doesn't seem to be passing itself as an argument to the new function anymore like it does with its own methods, anything I can do to remedy that?
I tried including hybrid_type2 inside the class as well and then using self.hybrid_fun = self.hybrid_type2 works, but using self.hybrid_fun = OrigObject.hybrid_fun causes a similar error (complaining that the first argument should be of type OrigObject). I know I can instead define OrigObject.hybrid_fun() logic inside OrigObject.hybrid_type1() so I can revert it back the same way I'm setting it (relative to the instance, rather than relative to the class to avoid having object not be the first argument). But I wanted to ask here if there is a cleaner approach I'm not seeing here? Thanks
EDIT:
Thanks guys, I've given points for several of the solutions that worked well. I essentially ended up using a Strategy pattern using types.MethodType(), I've accepted the answer that explained how to do the Strategy pattern in python (the Wikipedia article was more general, and the use of interfaces is not needed in Python).
Use the types module to create an instance method for a particular instance.
eg.
import types
def strategyA(possible_self):
pass
instance = OrigObject()
instance.strategy = types.MethodType(strategyA, instance)
instance.strategy()
Note that this only effects this specific instance, no other instances will be effected.
You want the Strategy Pattern.
Read about descriptors in Python. The next code should work:
else:
self.fybrid_fun = hybrid_type2.__get__(self, OrigObject)
What about defining it like so:
def hybrid_type2(someobj, a):
#do something else
...
def hybrid_type1(someobj, a):
#do something
...
class OrigObject(object):
def __init__(self):
...
self.run_the_fun = hybrid_type1
...
def hybrid_fun(self, a):
self.run_the_fun(self, a)
def type_switch(self, type):
if type == 1:
self.run_the_fun = hybrid_type1
else:
self.run_the_fun = hybrid_type2
You can change class at runtime:
class OrigObject(object):
...
def hybrid_fun(self, a):
#do something
...
def switch(self):
self.__class__ = DerivedObject
class DerivedObject(OrigObject):
def hybrid_fun(self, a):
#do the other thing
...
def switch(self):
self.__class__ = OrigObject
Lets say i have something like this:
This is file tree.py:
class leaf():
def green():
x = 100
This is file view.py:
from tree import leaf.green
g = green()
print g.x
How do i get the variable form subclass green
I know for class its just:
This is file tree.py:
class leaf():
x = 100
This is file view.py:
from tree import leaf
class view():
g = leaf()
print g.x
I understand how to do it if both classes are in the same file. But i dont understand in two seprate files.
Thanks,
John
I think the root of your problem is that you need to learn more about how classes in Python work. Fortunately, the tutorial in the Python docs has a section on classes.
If that doesn't help, going through something like Learn Python the Hard Way and doing the exercises can be immensely helpful.
x is local to the method, i.e. it shouldn't (and can't, at least not easily) be accessed from the outside. Worse - it only exists while the method runs (and is removed after it returns).
Note that you can assign an attribute to a method (to any function, really):
class Leaf(object):
def green(self):
...
green.x = 100
print Leaf.green.x
But that's propably not what you want (for starters, you can't access it as a local variable inside the method - because it isn't one) and in fact very rarely useful (unless you have a really good reason not to, just use a class).
I am developing a medium size program in python spread across 5 modules. The program accepts command line arguments using OptionParser in the main module e.g. main.py. These options are later used to determine how methods in other modules behave (e.g. a.py, b.py). As I extend the ability for the user to customise the behaviour or the program I find that I end up requiring this user-defined parameter in a method in a.py that is not directly called by main.py, but is instead called by another method in a.py:
main.py:
import a
p = some_command_line_argument_value
a.meth1(p)
a.py:
meth1(p):
# some code
res = meth2(p)
# some more code w/ res
meth2(p):
# do something with p
This excessive parameter passing seems wasteful and wrong, but has hard as I try I cannot think of a design pattern that solves this problem. While I had some formal CS education (minor in CS during my B.Sc.), I've only really come to appreciate good coding practices since I started using python. Please help me become a better programmer!
Create objects of types relevant to your program, and store the command line options relevant to each in them. Example:
import WidgetFrobnosticator
f = WidgetFrobnosticator()
f.allow_oncave_widgets = option_allow_concave_widgets
f.respect_weasel_pins = option_respect_weasel_pins
# Now the methods of WidgetFrobnosticator have access to your command-line parameters,
# in a way that's not dependent on the input format.
import PlatypusFactory
p = PlatypusFactory()
p.allow_parthenogenesis = option_allow_parthenogenesis
p.max_population = option_max_population
# The platypus factory knows about its own options, but not those of the WidgetFrobnosticator
# or vice versa. This makes each class easier to read and implement.
Maybe you should organize your code more into classes and objects? As I was writing this, Jimmy showed a class-instance based answer, so here is a pure class-based answer. This would be most useful if you only ever wanted a single behavior; if there is any chance at all you might want different defaults some of the time, you should use ordinary object-oriented programming in Python, i.e. pass around class instances with the property p set in the instance, not the class.
class Aclass(object):
p = None
#classmethod
def init_p(cls, value):
p = value
#classmethod
def meth1(cls):
# some code
res = cls.meth2()
# some more code w/ res
#classmethod
def meth2(cls):
# do something with p
pass
from a import Aclass as ac
ac.init_p(some_command_line_argument_value)
ac.meth1()
ac.meth2()
If "a" is a real object and not just a set of independent helper methods, you can create an "p" member variable in "a" and set it when you instantiate an "a" object. Then your main class will not need to pass "p" into meth1 and meth2 once "a" has been instantiated.
[Caution: my answer isn't specific to python.]
I remember that Code Complete called this kind of parameter a "tramp parameter". Googling for "tramp parameter" doesn't return many results, however.
Some alternatives to tramp parameters might include:
Put the data in a global variable
Put the data in a static variable of a class (similar to global data)
Put the data in an instance variable of a class
Pseudo-global variable: hidden behind a singleton, or some dependency injection mechanism
Personally, I don't mind a tramp parameter as long as there's no more than one; i.e. your example is OK for me, but I wouldn't like ...
import a
p1 = some_command_line_argument_value
p2 = another_command_line_argument_value
p3 = a_further_command_line_argument_value
a.meth1(p1, p2, p3)
... instead I'd prefer ...
import a
p = several_command_line_argument_values
a.meth1(p)
... because if meth2 decides that it wants more data than before, I'd prefer if it could extract this extra data from the original parameter which it's already being passed, so that I don't need to edit meth1.
With objects, parameter lists should normally be very small, since most appropriate information is a property of the object itself. The standard way to handle this is to configure the object properties and then call the appropriate methods of that object. In this case set p as an attribute of a. Your meth2 should also complain if p is not set.
Your example is reminiscent of the code smell Message Chains. You may find the corresponding refactoring, Hide Delegate, informative.