<stringname>.capitalize VS. str.capitalize(<stringname>) [duplicate] - python

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

Related

How can I unit test code which uses a confluent_kafka Consumer? [duplicate]

Ruby can add methods to the Number class and other core types to get effects like this:
1.should_equal(1)
But it seems like Python cannot do this. Is this true? And if so, why? Does it have something to do with the fact that type can't be modified?
Rather than talking about different definitions of monkey patching, I would like to just focus on the example above. I have already concluded that it cannot be done as a few of you have answered. But I would like a more detailed explanation of why it cannot be done, and maybe what feature, if available in Python, would allow this.
To answer some of you: The reason I might want to do this is simply aesthetics/readability.
item.price.should_equal(19.99)
This reads more like English and clearly indicates which is the tested value and which is the expected value, as supposed to:
should_equal(item.price, 19.99)
This concept is what Rspec and some other Ruby frameworks are based on.
No, you cannot. In Python, all data (classes, methods, functions, etc) defined in C extension modules (including builtins) are immutable. This is because C modules are shared between multiple interpreters in the same process, so monkeypatching them would also affect unrelated interpreters in the same process. (Multiple interpreters in the same process are possible through the C API, and there has been some effort towards making them usable at Python level.)
However, classes defined in Python code may be monkeypatched because they are local to that interpreter.
What exactly do you mean by Monkey Patch here? There are several slightly different definitions.
If you mean, "can you change a class's methods at runtime?", then the answer is emphatically yes:
class Foo:
pass # dummy class
Foo.bar = lambda self: 42
x = Foo()
print x.bar()
If you mean, "can you change a class's methods at runtime and make all of the instances of that class change after-the-fact?" then the answer is yes as well. Just change the order slightly:
class Foo:
pass # dummy class
x = Foo()
Foo.bar = lambda self: 42
print x.bar()
But you can't do this for certain built-in classes, like int or float. These classes' methods are implemented in C and there are certain abstractions sacrificed in order to make the implementation easier and more efficient.
I'm not really clear on why you would want to alter the behavior of the built-in numeric classes anyway. If you need to alter their behavior, subclass them!!
You can do this, but it takes a little bit of hacking. Fortunately, there's a module now called "Forbidden Fruit" that gives you the power to patch methods of built-in types very simply. You can find it at
http://clarete.github.io/forbiddenfruit/?goback=.gde_50788_member_228887816
or
https://pypi.python.org/pypi/forbiddenfruit/0.1.0
With the original question example, after you write the "should_equal" function, you'd just do
from forbiddenfruit import curse
curse(int, "should_equal", should_equal)
and you're good to go! There's also a "reverse" function to remove a patched method.
def should_equal_def(self, value):
if self != value:
raise ValueError, "%r should equal %r" % (self, value)
class MyPatchedInt(int):
should_equal=should_equal_def
class MyPatchedStr(str):
should_equal=should_equal_def
import __builtin__
__builtin__.str = MyPatchedStr
__builtin__.int = MyPatchedInt
int(1).should_equal(1)
str("44").should_equal("44")
Have fun ;)
Python's core types are immutable by design, as other users have pointed out:
>>> int.frobnicate = lambda self: whatever()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'int'
You certainly could achieve the effect you describe by making a subclass, since user-defined types in Python are mutable by default.
>>> class MyInt(int):
... def frobnicate(self):
... print 'frobnicating %r' % self
...
>>> five = MyInt(5)
>>> five.frobnicate()
frobnicating 5
>>> five + 8
13
There's no need to make the MyInt subclass public, either; one could just as well define it inline directly in the function or method that constructs the instance.
There are certainly a few situations where Python programmers who are fluent in the idiom consider this sort of subclassing the right thing to do. For instance, os.stat() returns a tuple subclass that adds named members, precisely in order to address the sort of readability concern you refer to in your example.
>>> import os
>>> st = os.stat('.')
>>> st
(16877, 34996226, 65024L, 69, 1000, 1000, 4096, 1223697425, 1223699268, 1223699268)
>>> st[6]
4096
>>> st.st_size
4096
That said, in the specific example you give, I don't believe that subclassing float in item.price (or elsewhere) would be very likely to be considered the Pythonic thing to do. I can easily imagine somebody deciding to add a price_should_equal() method to item if that were the primary use case; if one were looking for something more general, perhaps it might make more sense to use named arguments to make the intended meaning clearer, as in
should_equal(observed=item.price, expected=19.99)
or something along those lines. It's a bit verbose, but no doubt it could be improved upon. A possible advantage to such an approach over Ruby-style monkey-patching is that should_equal() could easily perform its comparison on any type, not just int or float. But perhaps I'm getting too caught up in the details of the particular example that you happened to provide.
You can't patch core types in python.
However, you could use pipe to write a more human readable code:
from pipe import *
#Pipe
def should_equal(obj, val):
if obj==val: return True
return False
class dummy: pass
item=dummy()
item.value=19.99
print item.value | should_equal(19.99)
If you really really really want to do a monkey patch in Python, you can do a (sortof) hack with the "import foo as bar" technique.
If you have a class such as TelnetConnection, and you want to extend it, subclass it in a separate file and call it something like TelnetConnectionExtended.
Then, at the top of your code, where you would normally say:
import TelnetConnection
change that to be:
import TelnetConnectionExtended as TelnetConnection
and then everywhere in your code that you reference TelnetConnection will actually be referencing TelnetConnectionExtended.
Sadly, this assumes that you have access to that class, and the "as" only operates within that particular file (it's not a global-rename), but I've found it to be useful from time to time.
Here's an example of implementing item.price.should_equal, although I'd use Decimal instead of float in a real program:
class Price(float):
def __init__(self, val=None):
float.__init__(self)
if val is not None:
self = val
def should_equal(self, val):
assert self == val, (self, val)
class Item(object):
def __init__(self, name, price=None):
self.name = name
self.price = Price(price)
item = Item("spam", 3.99)
item.price.should_equal(3.99)
No but you have UserDict UserString and UserList which were made with exactly this in mind.
If you google you will find examples for other types, but this are builtin.
In general monkey patching is less used in Python than in Ruby.
What does should_equal do? Is it a boolean returning True or False? In that case, it's spelled:
item.price == 19.99
There's no accounting for taste, but no regular python developer would say that's less readable than your version.
Does should_equal instead set some sort of validator? (why would a validator be limited to one value? Why not just set the value and not update it after that?) If you want a validator, this could never work anyway, since you're proposing to modify either a particular integer or all integers. (A validator that requires 18.99 to equal 19.99 will always fail.) Instead, you could spell it like this:
item.price_should_equal(19.99)
or this:
item.should_equal('price', 19.99)
and define appropriate methods on item's class or superclasses.
It seems what you really wanted to write is:
assert item.price == 19.99
(Of course comparing floats for equality, or using floats for prices, is a bad idea, so you'd write assert item.price == Decimal(19.99) or whatever numeric class you were using for the price.)
You could also use a testing framework like py.test to get more info on failing asserts in your tests.
No, you can't do that in Python. I consider it to be a good thing.
No, sadly you cannot extend types implemented in C at runtime.
You can subclass int, although it is non-trivial, you may have to override __new__.
You also have a syntax issue:
1.somemethod() # invalid
However
(1).__eq__(1) # valid
Here is how I made custom string/int/float...etc. methods:
class MyStrClass(str):
def __init__(self, arg: str):
self.arg_one = arg
def my_str_method(self):
return self.arg_one
def my_str_multiple_arg_method(self, arg_two):
return self.arg_one + arg_two
class MyIntClass(int):
def __init__(self, arg: int):
self.arg_one = arg
def my_int_method(self):
return self.arg_one * 2
myString = MyStrClass("StackOverflow")
myInteger = MyIntClass(15)
print(myString.count("a")) # Output: 1
print(myString.my_str_method()) # Output: StackOverflow
print(myString.my_str_multiple_arg_method(" is cool!")) # Output: StackOverflow is cool!
print(myInteger.my_int_method()) # Output: 30
It's maybe not the best solution, but it works just fine.
Here's how I achieve the .should_something... behavior:
result = calculate_result('blah') # some method defined somewhere else
the(result).should.equal(42)
or
the(result).should_NOT.equal(41)
I included a decorator method for extending this behavior at runtime on a stand-alone method:
#should_expectation
def be_42(self)
self._assert(
action=lambda: self._value == 42,
report=lambda: "'{0}' should equal '5'.".format(self._value)
)
result = 42
the(result).should.be_42()
You have to know a bit about the internals but it works.
Here's the source:
https://github.com/mdwhatcott/pyspecs
It's also on PyPI under pyspecs.

In Python, how can I use an attribute as both and attribute and a method/callable?

This is kindof an experiment. I'm interested in an API that supports both of these syntaxes:
obj.thing
--> returns default value
obj.thing(2, 'a')
--> returns value derived from *args and **kwargs
"thing" is the same object in both cases; I'd like the calling of thing to be optional (or implicit, if there are not () after it).
I tried over-riding __repr__, but that's just the visual representation of the the object itself, and what is actually returned is an instance of the containing object (here, 'obj'). So, no good.
I'm thinking that there would be an attribute set on an object that was a callable (don't care if it's an instance, a def, or just __call__ on the object) that has enough default values:
class CallableDefault(object):
__call__(self, num=3, letter="z"):
return letter * num
class DumbObject(object):
foo = CallableDefault()
obj = DumbObject()
so, ideally, doing obj alone would return "zzz", but one could also do obj(7,'a') and get 'aaaaaaa'.
I'm thinking decorators might be the way to do this, but I'm not great with decorators. One could override the getattr() call on the containing class, but that would mean that it has to be in a containing class that supports this feature.
What you describe could work, but notice that now the value of the attribute is constrained to be an object of your CallableDefault class. This probably won't be very useful.
I strongly suggest that you don't try to do this. For one thing, you're spending a lot of time trying to trick Python into doing something it doesn't want to do. For another, the users of your API will be confused because it acts differently than every other Python code they've ever seen. They will be confused.
Write a Python API that works naturally in Python.
What happens when you do either
obj.thing
or
obj.thing(2, 'a')
is Python goes looking for thing on obj; once it has thing it either returns it (first case above), or calls it with the parameters (second case) -- the critical point being that the call does not happen until after the attribute is retrieved -- and the containing class has no way of knowing if the thing it returns will be called or not.
You could add a __call__ method to every type you might use this way, but that way lies madness.
Update
Well, as long as you're comfortable with insanity, you could try something like this:
class CallableStr(str):
def __call__(self, num, letter):
return num*letter
class CallableInt(int):
def __call__(self, num, pow):
return num ** pow
class Tester(object):
wierd = CallableStr('zzz')
big = CallableInt(3)
t = Tester()
print repr(t.wierd)
print repr(t.wierd(7, 'a'))
print repr(t.big)
print repr(t.big(2, 16))
One nice thing about this magic object is that it becomes normal soon as you use it in a calculation (or call):
print type(t.big), type(t.big + 3), t.big + 3
print type(t.big), type(t.big(2, 3) + 9), t.big(2, 3) + 9
which results in
<class '__main__.CallableInt'> <type 'int'> 6
<class '__main__.CallableInt'> <type 'int'> 17

Overwriting class methods without inheritance (python)

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

How to avoid excessive parameter passing?

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.

Can you monkey patch methods on core types in Python?

Ruby can add methods to the Number class and other core types to get effects like this:
1.should_equal(1)
But it seems like Python cannot do this. Is this true? And if so, why? Does it have something to do with the fact that type can't be modified?
Rather than talking about different definitions of monkey patching, I would like to just focus on the example above. I have already concluded that it cannot be done as a few of you have answered. But I would like a more detailed explanation of why it cannot be done, and maybe what feature, if available in Python, would allow this.
To answer some of you: The reason I might want to do this is simply aesthetics/readability.
item.price.should_equal(19.99)
This reads more like English and clearly indicates which is the tested value and which is the expected value, as supposed to:
should_equal(item.price, 19.99)
This concept is what Rspec and some other Ruby frameworks are based on.
No, you cannot. In Python, all data (classes, methods, functions, etc) defined in C extension modules (including builtins) are immutable. This is because C modules are shared between multiple interpreters in the same process, so monkeypatching them would also affect unrelated interpreters in the same process. (Multiple interpreters in the same process are possible through the C API, and there has been some effort towards making them usable at Python level.)
However, classes defined in Python code may be monkeypatched because they are local to that interpreter.
What exactly do you mean by Monkey Patch here? There are several slightly different definitions.
If you mean, "can you change a class's methods at runtime?", then the answer is emphatically yes:
class Foo:
pass # dummy class
Foo.bar = lambda self: 42
x = Foo()
print x.bar()
If you mean, "can you change a class's methods at runtime and make all of the instances of that class change after-the-fact?" then the answer is yes as well. Just change the order slightly:
class Foo:
pass # dummy class
x = Foo()
Foo.bar = lambda self: 42
print x.bar()
But you can't do this for certain built-in classes, like int or float. These classes' methods are implemented in C and there are certain abstractions sacrificed in order to make the implementation easier and more efficient.
I'm not really clear on why you would want to alter the behavior of the built-in numeric classes anyway. If you need to alter their behavior, subclass them!!
You can do this, but it takes a little bit of hacking. Fortunately, there's a module now called "Forbidden Fruit" that gives you the power to patch methods of built-in types very simply. You can find it at
http://clarete.github.io/forbiddenfruit/?goback=.gde_50788_member_228887816
or
https://pypi.python.org/pypi/forbiddenfruit/0.1.0
With the original question example, after you write the "should_equal" function, you'd just do
from forbiddenfruit import curse
curse(int, "should_equal", should_equal)
and you're good to go! There's also a "reverse" function to remove a patched method.
def should_equal_def(self, value):
if self != value:
raise ValueError, "%r should equal %r" % (self, value)
class MyPatchedInt(int):
should_equal=should_equal_def
class MyPatchedStr(str):
should_equal=should_equal_def
import __builtin__
__builtin__.str = MyPatchedStr
__builtin__.int = MyPatchedInt
int(1).should_equal(1)
str("44").should_equal("44")
Have fun ;)
Python's core types are immutable by design, as other users have pointed out:
>>> int.frobnicate = lambda self: whatever()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'int'
You certainly could achieve the effect you describe by making a subclass, since user-defined types in Python are mutable by default.
>>> class MyInt(int):
... def frobnicate(self):
... print 'frobnicating %r' % self
...
>>> five = MyInt(5)
>>> five.frobnicate()
frobnicating 5
>>> five + 8
13
There's no need to make the MyInt subclass public, either; one could just as well define it inline directly in the function or method that constructs the instance.
There are certainly a few situations where Python programmers who are fluent in the idiom consider this sort of subclassing the right thing to do. For instance, os.stat() returns a tuple subclass that adds named members, precisely in order to address the sort of readability concern you refer to in your example.
>>> import os
>>> st = os.stat('.')
>>> st
(16877, 34996226, 65024L, 69, 1000, 1000, 4096, 1223697425, 1223699268, 1223699268)
>>> st[6]
4096
>>> st.st_size
4096
That said, in the specific example you give, I don't believe that subclassing float in item.price (or elsewhere) would be very likely to be considered the Pythonic thing to do. I can easily imagine somebody deciding to add a price_should_equal() method to item if that were the primary use case; if one were looking for something more general, perhaps it might make more sense to use named arguments to make the intended meaning clearer, as in
should_equal(observed=item.price, expected=19.99)
or something along those lines. It's a bit verbose, but no doubt it could be improved upon. A possible advantage to such an approach over Ruby-style monkey-patching is that should_equal() could easily perform its comparison on any type, not just int or float. But perhaps I'm getting too caught up in the details of the particular example that you happened to provide.
You can't patch core types in python.
However, you could use pipe to write a more human readable code:
from pipe import *
#Pipe
def should_equal(obj, val):
if obj==val: return True
return False
class dummy: pass
item=dummy()
item.value=19.99
print item.value | should_equal(19.99)
If you really really really want to do a monkey patch in Python, you can do a (sortof) hack with the "import foo as bar" technique.
If you have a class such as TelnetConnection, and you want to extend it, subclass it in a separate file and call it something like TelnetConnectionExtended.
Then, at the top of your code, where you would normally say:
import TelnetConnection
change that to be:
import TelnetConnectionExtended as TelnetConnection
and then everywhere in your code that you reference TelnetConnection will actually be referencing TelnetConnectionExtended.
Sadly, this assumes that you have access to that class, and the "as" only operates within that particular file (it's not a global-rename), but I've found it to be useful from time to time.
Here's an example of implementing item.price.should_equal, although I'd use Decimal instead of float in a real program:
class Price(float):
def __init__(self, val=None):
float.__init__(self)
if val is not None:
self = val
def should_equal(self, val):
assert self == val, (self, val)
class Item(object):
def __init__(self, name, price=None):
self.name = name
self.price = Price(price)
item = Item("spam", 3.99)
item.price.should_equal(3.99)
No but you have UserDict UserString and UserList which were made with exactly this in mind.
If you google you will find examples for other types, but this are builtin.
In general monkey patching is less used in Python than in Ruby.
What does should_equal do? Is it a boolean returning True or False? In that case, it's spelled:
item.price == 19.99
There's no accounting for taste, but no regular python developer would say that's less readable than your version.
Does should_equal instead set some sort of validator? (why would a validator be limited to one value? Why not just set the value and not update it after that?) If you want a validator, this could never work anyway, since you're proposing to modify either a particular integer or all integers. (A validator that requires 18.99 to equal 19.99 will always fail.) Instead, you could spell it like this:
item.price_should_equal(19.99)
or this:
item.should_equal('price', 19.99)
and define appropriate methods on item's class or superclasses.
It seems what you really wanted to write is:
assert item.price == 19.99
(Of course comparing floats for equality, or using floats for prices, is a bad idea, so you'd write assert item.price == Decimal(19.99) or whatever numeric class you were using for the price.)
You could also use a testing framework like py.test to get more info on failing asserts in your tests.
No, you can't do that in Python. I consider it to be a good thing.
No, sadly you cannot extend types implemented in C at runtime.
You can subclass int, although it is non-trivial, you may have to override __new__.
You also have a syntax issue:
1.somemethod() # invalid
However
(1).__eq__(1) # valid
Here is how I made custom string/int/float...etc. methods:
class MyStrClass(str):
def __init__(self, arg: str):
self.arg_one = arg
def my_str_method(self):
return self.arg_one
def my_str_multiple_arg_method(self, arg_two):
return self.arg_one + arg_two
class MyIntClass(int):
def __init__(self, arg: int):
self.arg_one = arg
def my_int_method(self):
return self.arg_one * 2
myString = MyStrClass("StackOverflow")
myInteger = MyIntClass(15)
print(myString.count("a")) # Output: 1
print(myString.my_str_method()) # Output: StackOverflow
print(myString.my_str_multiple_arg_method(" is cool!")) # Output: StackOverflow is cool!
print(myInteger.my_int_method()) # Output: 30
It's maybe not the best solution, but it works just fine.
Here's how I achieve the .should_something... behavior:
result = calculate_result('blah') # some method defined somewhere else
the(result).should.equal(42)
or
the(result).should_NOT.equal(41)
I included a decorator method for extending this behavior at runtime on a stand-alone method:
#should_expectation
def be_42(self)
self._assert(
action=lambda: self._value == 42,
report=lambda: "'{0}' should equal '5'.".format(self._value)
)
result = 42
the(result).should.be_42()
You have to know a bit about the internals but it works.
Here's the source:
https://github.com/mdwhatcott/pyspecs
It's also on PyPI under pyspecs.

Categories