Adding convenience static / class methods without removing or breaking existing implementation - python

I am getting the hang of the OOP paradigm, and the art of making expandable and reusable code is something I want to improve at. Let's say in theory that I have a Python library of utility classes that has been widely used. I want to add some convenience static methods with the same code to a particular class for ease of use, but I don't want to break my existing use of the library. What is the recommended way to implement and name the new class methods? I have a couple of guesses as follows:
1) With an overloaded method name to maintain clarity? Python's not really a good example, but in other languages such as Java? For example:
class Cat(object):
def __init__(self, name):
self.name = name
def meow(self):
meow(self.name)
#staticmethod
def meow(name): # <-- Granted, Python doesn't overload method names
print "{} meowed cutely!".format(name)
2) With a different, perhaps less semantic static method name? The old name cannot be changed, so... This seems to me this could get out of hand for huge projects, with a bunch of non semantic names for just a static version of the same method. Example:
class Cat(object):
def __init__(self, name):
self.name = name
def meow(self):
meowFrom(self.name)
#staticmethod
def meowFrom(name): # Different, possibly less semantic name
print "{} meowed cutely!".format(name)
I assume duplicating the code outright is a bad idea. Which is the way to go? Or is there some better design pattern? Something specific for Python I am unaware of? I want to make sure my code isn't worthless in the future; and make some personal libraries that are expansive for future projects.

You can add optional parameters and keyword parameters to a function without breaking existing uses of it. For example, you could add a protocol=old argument to the end to choose which behavior to use, with the old behavior being default in the case of no explicit parameter. This is the best option if you want to keep the same function name, but it can quickly get unwieldy if you do it multiple times.

Related

"Hidden" attributes or duplicated code in python when using inheritance

I have a question about what I see as a potential bad habit when using inheritance in python
suppose I have a base class
class FourLeggedAnimal():
def __init__(self, name):
self.name = name
self.number_of_legs = 4
and two daughter classes
class Cat(FourLeggedAnimal):
def __init__(self, name):
super().__init__(name)
def claw_the_furniture(self):
for leg in range(self.number_of_legs):
print("scratch")
class Dog(FourLeggedAnimal):
def __init__(self, name):
super().__init__(name)
def run_in_sleep(self):
for leg in range(self.number_of_legs):
self.move_leg(leg)
def move_leg(i):
pass
For the purposes of this example, I intend to keep Animal in a different file than Cat. For someone reading the code for the Cat or Dog class, the number_of_legs attribute is used but not defined in the file. My understanding is that it is best not to have variables whose definitions are opaque (which is why its best to avoid from x import *.
I see the alternative to be repeating the definition self.number_of_legs in both daughter classes but that defeats the purposes of inheritance.
Is there a best-practice to deal with this kind of situation?
Is there a best-practice to deal with this kind of situation?
Normally, class variables are used for this purpose.
class FourLeggedAnimal():
number_of_legs = 4 # class variable
def __init__(self, name):
self.name = name
class Cat(FourLeggedAnimal):
def __init__(self, name):
super().__init__(name)
def claw_the_furniture(self):
for leg in range(self.number_of_legs):
print("scratch")
class Dog(FourLeggedAnimal):
def __init__(self, name):
super().__init__(name)
def run_in_sleep(self):
for leg in range(self.number_of_legs):
self.move_leg(leg)
def move_leg(i):
pass
Note that even if these classes are in different files, the attribute is part of the parent's public API and is knowable by the subclasses. Also, the class name, "FourLeggedAnimal" does a great job of communicating what the number of legs would be.
My understanding is that it is best not to have variables whose definitions are opaque (which is why its best to avoid from x import *.
I think perhaps you are misunderstanding the source of this advice. It may even be a mix of different pieces of advice. I'll try to explain what I think might have been the underlying ideas people were trying to convey.
Firstly, it's pretty widely agreed that from x import * is best avoided in Python. This is because it makes it hard for readers to find out where a name comes from or indeed if it's defined at all. It also confuses some code analysis tools. It's the only way that a (non-builtin) name will normally get into a top level namespace without appearing in the source code and being easy to search for. As far as this advice goes, it's only for this case. You could barely write Python code at all if you couldn't use fields and methods on objects, and you generally have a clear breadcrumb trail to follow. (Moreso if you're using type annotations.)
However, you may also be thinking of the principle of encapsulation. In object-oriented programming it's considered preferable to separate the interface from the implementation of your objects. You make the interface as small, simple and clear as you can and hide away the implementation from the code using the objects. In this way you can reason about and change the implementation in isolation, with confidence that doing so won't affect other code. This principle is applied even between base classes and sub-classes - the sub-class shouldn't "know" anything about the base class that it doesn't need to. Now, modifying variables, and to a lesser extent reading modifiable variables requires knowing an awful lot about what expectations the base class has for their values, their relationship with other state and when it's possible/permissible for them to change. Depending on them can make it much harder to safely change the base class.
Now, Python does have more flexibility than some other languages in this respect. In Python you can seamlessly replace a variable with a property, and thus make "reading" and "setting" a field into methods that you can implement however you want. In other languages once a sub-class starts using a field exposed by a base class it is impossible to refactor the base class to remove the field or add any extra behaviour when it is accessed, unless you also update all the sub-classes. So it's a bit less of a concern. Or rather, there's no particular reason to treat fields differently from methods.
With all this in mind, the question becomes - what interface is your base class presenting to its sub-classes? Does it support them setting as well as reading this field? Can you reduce the size and complexity of the interface between the two classes without making your code more complex? An interface is simpler and easier to reason about if it is read-only, and moreso if it does not involve mutable state at all. Where possible the base class should not give the sub-class any unnecessary opportunities to break its invariants. (I.e. it's expectations about its own state.) In Python these things are more often achieved through convention (e.g. fields and methods beginning with an underscore are considered not to be part of the public interface unless documented otherwise) and documentation than through language features.

Python class and methods - best practice for accessing and altering attributes?

TLDR: What's best practice for accessing and altering attributes of a class instance?
Let's say we have a class to generate an object that is intended to hold data about a product (e.g. maybe a product master dataset).
class StoreProduct(object):
def __init__(self,ProductID,ProductPrice,ProductDescription):
self.ProductID = ProductID
self.ProductPrice = ProductPrice
self.ProductDescription = ProductDescription
def ChangeProductPrice(self, newProductPrice):
self.ProductPrice = newProductPrice
And we have another class we may be able to use to access those instances generated by StoreProduct(), with methods for making adjustments / changes.
class ChangeProductData(object):
def __init__(self):
pass
#staticmethod
def ChangeProductObjectPrice(newProductPrice,ProductObject):
ProductObject.ProductPrice = newProductPrice
So we generate an instance named Product1:
Product1 = StoreProduct(
ProductID="Product1",
ProductPrice=4,
ProductDescription="A nice lamp"
)
What's best practice coding for reading and/or altering class instances?
If I wanted to alter an attribute in Product 1 (in this case the price) is something like this acceptable in general, or is it bad code?
Method 1
ChangeProductData().ChangeProductObjectPrice(8,Product1)
Or is this the preferred way to do it?
Method 2
Product1.ChangeProductPrice(2)
When might there be exceptions?
While the above are simplified situations, what I've currently read seems to indicate that Method 2 might be better practice. However, wouldn't Method 1 provide greater flexibility in future (e.g. if you need to change how a method works, or add new methods).
I have also been reading into getattr() and setattr(), but people seem to be mixed on whether its better than using dot (e.g. Product1.ProductPrice to get the price).
Definitely method 2. As #user2357112 mentions, method 1 doesn't make sense.
As you rightly pointed out, this is a simple scenario and the pythonic way would be use property
class StoreProduct(object): # minor: please notice the PEP styling
def __init__(self, product_price):
self._price = produce_price
# other attributes, omitted for brevity
#property
def product_price(self): # pythonic getter
return self._price
#product_price.setter
def product_price(self, new_price): # python setter
# you could do any custom validation before setting
self._price = new_price
Coming to the question of
I'm specifically tackling the issue of whether accessing and altering an class' attribute with another class is a big no-no.
Accessing: Accessing is okay here. In fact many design patterns that rely on composition heavily do this. e.g., adapter, strategy, decorator, command etc patterns
Altering: You want the class owning the attribute to be in charge of "altering". Foreign classes should only request to alter.
P.S. This is treading a bit along the lines of CQRS(Command Query Responsibility Segregation) pattern

How to split python class into multiple files [duplicate]

Using "new" style classes (I'm in python 3.2) is there a way to split a class over multiple files? I've got a large class (which really should be a single class from an object-oriented design perspective, considering coupling, etc, but it'd be nice to split over a few files just for ease of editing the class.
If your problem really is just working with a large class in an editor, the first solution I'd actually look for is a better way to break down the problem. The second solution would be a better editor, preferably one with code folding.
That said, there are a couple of ways you might break up a class into multiple files. Python lets you use a folder as a module by putting an __init__.py in it, which can then import things from other files. We'll use this capability in each solution. Make a folder called, say, bigclass first.
In the folder put the various .py files that will eventually comprise your class. Each should contain functions and variable definitions for the eventual class, not classes. In __init__.py in the same folder write the following to join them all together.
class Bigclass(object):
from classdef1 import foo, bar, baz, quux
from classdef2 import thing1, thing2
from classdef3 import magic, moremagic
# unfortunately, "from classdefn import *" is an error or warning
num = 42 # add more members here if you like
This has the advantage that you end up with a single class derived directly from object, which will look nice in your inheritance graphs.
You could use multiple inheritance to combine the various parts of your class. In your individual modules you would write a class definition for Bigclass with parts of the class. Then in your __init__.py write:
import classdef1, classdef2, classdef3
class Bigclass(classdef1.Bigclass, classdef2.Bigclass, classdef3.Bigclass):
num = 42 # add more members if desired
If the multiple inheritance becomes an issue, you can use single inheritance: just have each class inherit from another one in chain fashion. Assuming you don't define anything in more than one class, the order doesn't matter. For example, classdef2.py would be like:
import classdef1
class Bigclass(classdef1.Bigclass):
# more member defs here
classdef3 would import Bigclass from classdef2 and add to it, and so on. Your __init__.py would just import the last one:
from classdef42 import Bigclass
I'd generally prefer #1 because it's more explicit about what members you're importing from which files but any of these solutions could work for you.
To use the class in any of these scenarios you can just import it, using the folder name as the module name: from bigclass import Bigclass
You can do this with decorators like so:
class Car(object):
def start(self):
print 'Car has started'
def extends(klass):
def decorator(func):
setattr(klass, func.__name__, func)
return func
return decorator
#this can go in a different module/file
#extends(Car)
def do_start(self):
self.start()
#so can this
car = Car()
car.do_start()
#=> Car has started
Class definitions containing hundreds of lines do occur "in the wild" (I have seen some in popular open-source Python-based frameworks), but I believe that if you ponder what the methods are doing, it will be possible to reduce the length of most classes to a manageable point. Some examples:
Look for places where mostly the same code occurs more than once. Break that code out into its own method and call it from each place with arguments.
"Private" methods that do not use any of the object state can be brought out of the class as stand-alone functions.
Methods that should be called only under certain conditions may indicate a need to place those methods in a subclass.
To directly address your question, it is possible to split up the definition of a class. One way is to "monkey-patch" the class by defining it and then adding outside functions to it as methods. Another is to use the built-in type function to create the class "by hand", supplying its name, any base classes, and its methods and attributes in a dictionary. But I do not recommend doing this just because the definition would be long otherwise. That sort of cure is worse than the disease in my opinion.
I've previously toyed around with something similar. My usecase was a class hierarchy of nodes in an abstract syntax tree, and then I wanted to put all e.g. prettyprinting functions in a separate prettyprint.py file but still have them as methods in the classes.
One thing I tried was to use a decorator that puts the decorated function as an attribute on a specified class. In my case this would mean that prettyprint.py contains lots of def prettyprint(self) all decorated with different #inclass(...)
A problem with this is that one must make sure that the sub files are always imported, and that they depend on the main class, which makes for a circular dependency, which may be messy.
def inclass(kls):
"""
Decorator that adds the decorated function
as a method in specified class
"""
def _(func):
setattr(kls,func.__name__, func)
return func
return _
## exampe usage
class C:
def __init__(self, d):
self.d = d
# this would be in a separate file.
#inclass(C)
def meth(self, a):
"""Some method"""
print "attribute: %s - argument: %s" % (self.d, a)
i = C(10)
print i.meth.__doc__
i.meth(20)
I've not used it, but this package called partial claims to add support for partial classes.
It seems like there's a few other ways you could implement this yourself as well.
You could implement separate parts of the class as mixins in seperate files, then import them all somewhere and subclass them.
Alternatively, you could implement each of the methods of your class somewhere then in a central file import them and assign them as attributes on a class, to create the whole object. Like so:
a.py:
def AFunc( self, something ):
# Do something
pass
b.py:
def BFunc( self, something ):
# Do something else
pass
c.py:
import a, b
class C:
AFunc = a.AFunc
BFunc = b.BFunc
You could even go so far as to automate this process if you really wanted - loop through all the functions provided by modules a and b and then add them as attributes on C. Though that might be total overkill.
There might be other (possibly better) ways to go about it, but those are the 2 that popped into mind.
I would like to add that the pythonic way of doing this is through multiple inheritance, not necessarily using mixins. Instance attributes can be added using super().__init__(*args, **kwargs) in __init__ calls to pass arguments to baseclasses (see ‘super considered super’ presentation by Raymond Hettinger 1). This also enables dependency injection and kind of forces you to think about organization of base classes (it works best if only one baseclass sets an attribute in __init__ and all classes using the attribute inherit from it).
This does usually require you having control over the base classes (or they being written for this pattern).
Another option is using descriptors returning functions through __get__ to add functionality to classes in a decoupled way.
You could also look at __init_subclass__ to add e.g. methods to classes during class generation (i think added in python 3.6, but check)
First I'd like to say that something this complicated it probably not a good idea just to make finding your place in the class easier - it would be best to add comments, highlight sections etc. However, I see two ways you could do this:
Write the class in several files, then read them in as text, concatenate them and exec the resulting string.
Create a separate class in each file, then inherit them all into a master class as mixins. However, if you're subclassing another class already this could lead to MRO problems. You could get around this by creating a metaclass for your master class which manually resolves the MRO, but this could get messy.
The easiest would be the first option.
First off, I don't see how splitting the class into multiple files makes editing any easier. A decent IDE should be able to find any method easily whether in one file or multiple; if you're not using a decent IDE, splitting the class means the maintainer has to guess which file a given method is in, which sounds harder rather than easier.
More fundamentally, this class - so large that you want a special language feature just to support its weight - sounds fundamentally broken. How many lines of code are we talking about? Almost certainly, it would be a better idea to do one of:
Refactor duplicated code into fewer, more general primitives
Define a base class and extend it with subclasses as Karoly Horvath suggests in comments (this is the closest thing to the 'partial classes' that you're asking for that I would endorse)
Define a few separate classes to encapsulate different parts of this
class's functionality, and compose this class of instances of those
smaller ones.
I met the same situation - I want to slipt my class to 2 files.
the reason is that - I want part 1 for GUI layout, only layout
and another file keeps all function.
like c#'s Partial class. one for XAML and another one for functions.

Is it possible to divide functions of an python class into different files ? [duplicate]

Using "new" style classes (I'm in python 3.2) is there a way to split a class over multiple files? I've got a large class (which really should be a single class from an object-oriented design perspective, considering coupling, etc, but it'd be nice to split over a few files just for ease of editing the class.
If your problem really is just working with a large class in an editor, the first solution I'd actually look for is a better way to break down the problem. The second solution would be a better editor, preferably one with code folding.
That said, there are a couple of ways you might break up a class into multiple files. Python lets you use a folder as a module by putting an __init__.py in it, which can then import things from other files. We'll use this capability in each solution. Make a folder called, say, bigclass first.
In the folder put the various .py files that will eventually comprise your class. Each should contain functions and variable definitions for the eventual class, not classes. In __init__.py in the same folder write the following to join them all together.
class Bigclass(object):
from classdef1 import foo, bar, baz, quux
from classdef2 import thing1, thing2
from classdef3 import magic, moremagic
# unfortunately, "from classdefn import *" is an error or warning
num = 42 # add more members here if you like
This has the advantage that you end up with a single class derived directly from object, which will look nice in your inheritance graphs.
You could use multiple inheritance to combine the various parts of your class. In your individual modules you would write a class definition for Bigclass with parts of the class. Then in your __init__.py write:
import classdef1, classdef2, classdef3
class Bigclass(classdef1.Bigclass, classdef2.Bigclass, classdef3.Bigclass):
num = 42 # add more members if desired
If the multiple inheritance becomes an issue, you can use single inheritance: just have each class inherit from another one in chain fashion. Assuming you don't define anything in more than one class, the order doesn't matter. For example, classdef2.py would be like:
import classdef1
class Bigclass(classdef1.Bigclass):
# more member defs here
classdef3 would import Bigclass from classdef2 and add to it, and so on. Your __init__.py would just import the last one:
from classdef42 import Bigclass
I'd generally prefer #1 because it's more explicit about what members you're importing from which files but any of these solutions could work for you.
To use the class in any of these scenarios you can just import it, using the folder name as the module name: from bigclass import Bigclass
You can do this with decorators like so:
class Car(object):
def start(self):
print 'Car has started'
def extends(klass):
def decorator(func):
setattr(klass, func.__name__, func)
return func
return decorator
#this can go in a different module/file
#extends(Car)
def do_start(self):
self.start()
#so can this
car = Car()
car.do_start()
#=> Car has started
Class definitions containing hundreds of lines do occur "in the wild" (I have seen some in popular open-source Python-based frameworks), but I believe that if you ponder what the methods are doing, it will be possible to reduce the length of most classes to a manageable point. Some examples:
Look for places where mostly the same code occurs more than once. Break that code out into its own method and call it from each place with arguments.
"Private" methods that do not use any of the object state can be brought out of the class as stand-alone functions.
Methods that should be called only under certain conditions may indicate a need to place those methods in a subclass.
To directly address your question, it is possible to split up the definition of a class. One way is to "monkey-patch" the class by defining it and then adding outside functions to it as methods. Another is to use the built-in type function to create the class "by hand", supplying its name, any base classes, and its methods and attributes in a dictionary. But I do not recommend doing this just because the definition would be long otherwise. That sort of cure is worse than the disease in my opinion.
I've previously toyed around with something similar. My usecase was a class hierarchy of nodes in an abstract syntax tree, and then I wanted to put all e.g. prettyprinting functions in a separate prettyprint.py file but still have them as methods in the classes.
One thing I tried was to use a decorator that puts the decorated function as an attribute on a specified class. In my case this would mean that prettyprint.py contains lots of def prettyprint(self) all decorated with different #inclass(...)
A problem with this is that one must make sure that the sub files are always imported, and that they depend on the main class, which makes for a circular dependency, which may be messy.
def inclass(kls):
"""
Decorator that adds the decorated function
as a method in specified class
"""
def _(func):
setattr(kls,func.__name__, func)
return func
return _
## exampe usage
class C:
def __init__(self, d):
self.d = d
# this would be in a separate file.
#inclass(C)
def meth(self, a):
"""Some method"""
print "attribute: %s - argument: %s" % (self.d, a)
i = C(10)
print i.meth.__doc__
i.meth(20)
I've not used it, but this package called partial claims to add support for partial classes.
It seems like there's a few other ways you could implement this yourself as well.
You could implement separate parts of the class as mixins in seperate files, then import them all somewhere and subclass them.
Alternatively, you could implement each of the methods of your class somewhere then in a central file import them and assign them as attributes on a class, to create the whole object. Like so:
a.py:
def AFunc( self, something ):
# Do something
pass
b.py:
def BFunc( self, something ):
# Do something else
pass
c.py:
import a, b
class C:
AFunc = a.AFunc
BFunc = b.BFunc
You could even go so far as to automate this process if you really wanted - loop through all the functions provided by modules a and b and then add them as attributes on C. Though that might be total overkill.
There might be other (possibly better) ways to go about it, but those are the 2 that popped into mind.
I would like to add that the pythonic way of doing this is through multiple inheritance, not necessarily using mixins. Instance attributes can be added using super().__init__(*args, **kwargs) in __init__ calls to pass arguments to baseclasses (see ‘super considered super’ presentation by Raymond Hettinger 1). This also enables dependency injection and kind of forces you to think about organization of base classes (it works best if only one baseclass sets an attribute in __init__ and all classes using the attribute inherit from it).
This does usually require you having control over the base classes (or they being written for this pattern).
Another option is using descriptors returning functions through __get__ to add functionality to classes in a decoupled way.
You could also look at __init_subclass__ to add e.g. methods to classes during class generation (i think added in python 3.6, but check)
First I'd like to say that something this complicated it probably not a good idea just to make finding your place in the class easier - it would be best to add comments, highlight sections etc. However, I see two ways you could do this:
Write the class in several files, then read them in as text, concatenate them and exec the resulting string.
Create a separate class in each file, then inherit them all into a master class as mixins. However, if you're subclassing another class already this could lead to MRO problems. You could get around this by creating a metaclass for your master class which manually resolves the MRO, but this could get messy.
The easiest would be the first option.
First off, I don't see how splitting the class into multiple files makes editing any easier. A decent IDE should be able to find any method easily whether in one file or multiple; if you're not using a decent IDE, splitting the class means the maintainer has to guess which file a given method is in, which sounds harder rather than easier.
More fundamentally, this class - so large that you want a special language feature just to support its weight - sounds fundamentally broken. How many lines of code are we talking about? Almost certainly, it would be a better idea to do one of:
Refactor duplicated code into fewer, more general primitives
Define a base class and extend it with subclasses as Karoly Horvath suggests in comments (this is the closest thing to the 'partial classes' that you're asking for that I would endorse)
Define a few separate classes to encapsulate different parts of this
class's functionality, and compose this class of instances of those
smaller ones.
I met the same situation - I want to slipt my class to 2 files.
the reason is that - I want part 1 for GUI layout, only layout
and another file keeps all function.
like c#'s Partial class. one for XAML and another one for functions.

Accessing private variables when there's a getter/setter for them

I have a question about righteous way of programming in Python... Maybe there can be several different opinions, but here it goes:
Let's say I have a class with a couple of private attributes and that I have implemented two getters/setters (not overloading __getattr__ and __setattr__, but in a more “Java-tistic” style):
class MyClass:
def __init__(self):
self.__private1 = "Whatever1"
def setPrivate1(self, private1):
if isinstance(private1, str) and (private1.startswith("private")):
self.__private1 = private1
else:
raise AttributeError("Kaputt")
def getPrivate1(self):
return self.__private1
Now let's say a few lines below, in another method of the same class, I need to re-set the value of that “__private1”. Since it's the same class, I still have direct access to the private attribute self.__private1.
My question is: Should I use:
self.setPrivate1("privateBlaBlaBla")
or should I access directly as:
self.__private1 ="privateBlaBlaBla"
since I am the one setting the new value, I know that said value (“privateBlaBlaBla”) is correct (an str() that starts with “private”), so it is not going to leave the system inconsistent. On the other hand, if another programmer takes my code, and needs to change the functionality for the self.__private1 attribute, he will need to go through all the code, and see if the value of __private1 has been manually set somewhere else.
My guess is that the right thing to do is to always using the setPrivate1 method, and only access directly the __private1 variable in the get/set, but I'd like to know the opinion of more experienced Python programmers.
You can't present a classic example of bad Python and then expect people to have opinions on what do to about it. Use getters and setters.
class MyClass:
def __init__(self):
self._private1 = "Whatever1"
#property
def private1(self):
return self._private1
#private1.setter
def private1(self, value):
self._private1 = value
A side comment -- using double underscore names can be confusing, because Python actually mangles the name to stop you accessing them from outside the class. This provides no real security, but causes no end of headaches. The easiest way to avoid the headaches is to use single-underscore names, which is basically a universal convention for private. (Ish.)
If you want an opinion -- use properties =). If you want an opinion on your JavaPython monstrosity, I would use the setter -- after all, you've written it, that's what it's there for! There's no obvious benefit to setting the variable by hand, but there are several drawbacks.
Neither. In Python, use properties, not getters and setters.
class MyClass:
def __init__(self):
self._private1 = "Whatever1"
#property
def private1(self):
return self._private1
#private1.setter
def private1(self, private1):
if isinstance(private1, str) and (private1.startswith("private")):
self._private1 = private1
else:
raise AttributeError("Kaputt")
Then later on in your code, set the _private1 attribute with
self.private1="privateBlaBlaBla"

Categories