Is it safe or advised to use dynamic attribute with python? - python

My question is not really technical. I use a python package with well suited classes which contain numerous attributes and methods. But for my application I would like to store several additional attributes which do not exist in that classes.
Using python, if I set an attribute that does not exist in the class, python just create that attribute. It works. But my question is to know if this is recommended or if I must implement a subclass with that additional attributes ? For example it will allow us to document that new attributes etc ...

In a sense, this is slightly subjective but there is a clear answer. Do not add new attributes to the original object, create a new class.
I could argue about at least one clear reason for that. A new attribute is making the object do more than it used to do, so it is surely violating the single responsibility principle.
So, create a new class to hold this data. Yet, we could give you more information if we actually knew what you are trying to do. So, what about adding some more info?

Related

Functions for adding nested data to model, inside or outside the model?

suppose I have a class/model building that has a relation to the class/model wall and this again to the class/model window in a form that one building can have many surfaces and a surface can have many windows (one to many).
Now when I want to add windows to that building, maybe also only to certain surfaces, should the functions(also search functions/loops) be written inside the model? Or outside in a separate class/script that is either called from the model or called from outside?
I could imagine, when the functionality is part of the model, that it could cause problems when changes are needed in the long run.
What is the cleaner architecture/standard since both could work?
If possible can you give me a source to read more into this certain problem?
In my case I'm using python with sqlalchemy and postgres, but this question could also be legitimate for other programming languages.
(I hope this question is not too broad/ opinion based)
For starters, I think this question might have been better asked in Softwareengineering. However, I might as well give you my few cents on this.
As so often, it depends ...
Generally, encapsulation is one of the core concepts in object-oriented programming.
Any change to the state of an object should be done by the object itself (although potentially triggered externally) and therefore be guaranteed to comply with the terms and conditions you defined for your object. The behavior of your object should be implemented inside your object not outside of it.
You don't want to expose your Window's attribute wall publicly for all the world to access it directly. You want to hide it behind getters and setters. You want the Window to refuse being placed on a Wall that is passed to its wall setter if said Wall happens to be 'interior'. You don't want a Person object to change the Window's state from 'open' to 'close' and vice versa directly, you want the Person to call the Window's open() resp. close() method, e.g. to ensure internally that a closed window is not closed again.
Also, hiding implementation details can help maintaining your interface and making changes to your class transparent. Say, for example, you decide that, in addition to disallow interior walls, you now also want to prevent "normal" windows from being put into exterior walls in the basement. You can implement that check into your existing wall setter in Window and the only visible change for external code would be another potential reason for refusal ("window=normal and wall=basement" in addition to "wall=interior"). Or you want to add an attribute representing the state of cleanliness of your Window and, to make a proper distinction between the new cleanliness_state and the old 'open'/'close' state, you want to rename the old attribute to open_close_state. With your methods open(), close() (and potentially is_open() and is_closed()) reading from and writing to your 'open'/'close' state attribute, this change just affects your class implementation, not every piece of code that uses it.
However!
You might have classes that just work as some sort of collection, i.e. data classes. These implement little to no functionality and publicly expose their attributes to be read and written by the whole world, thus broadly ignoring the concept of encapsulation. One could argue that classes/models implemented in an object-relational mapping layer, such as SQLAlchemy, are more of a data object/data class than an object in the OOP sense, especially when used mainly to persist and retrieve structured data. It is not unusual to have external code change the state of such an object or implement its functionality, like the views in the Django framework that uses its own ORM layer to implement and persist models.
So?
It boils down to your concrete case. You already mentioned that you consider restricting the placement of windows; probably based on properties of the windows and walls involved.
If you consider your SQLAlchemy models more than just a way of persisting your objects, go ahead and implement the behavior and change logic right away in your model. But keep in mind that a) you might end up creating conflicts with methods/properties of your model's base class and b) the attributes of your models must remain publicly exposed to maintain the functionality of your ORM layer (Although SQLAlchemy might be able to work with properties as long as both, getter and setter are defined; I have never tested that).
If you want the models to be a rather convenient method of persisting and retrieving your structured data, keep them clean and go for some utility functions or classes that implement your object's behavior and ensure its contract when being used in the code; e.g. have a function place_window_on_wall(window: Window, wall: Wall) that takes care of validation and restrictions when you try to reference a Wall object on your Window's wall attribute. But keep in mind that changes to your model must be reflected in these functions / classes as well.
I consider both options valid; just whatever you opt for, be consistent with your decision.

Python: Data Object or class

I enjoy all the python libraries for scraping websites and I am experimenting with BeautifulSoup and IMDB just for fun.
As I come from Java, I have some Java-practices incorporated into my programming styles. I am trying to get the info of a certain movie, I can either create a Movie class or just use a dictionary with keys for the attributes.
My question is, should I just use dictionaries when a class will only contain data and perhaps almost no behaviour? In other languages creating a type will help you enforce certain restrictions and because of type checks the IDE will help you program, this is not always the case in python, so what should I do?
Should I resort to creating a class only when there's both, behaviour and data? Or create a movie class even though it'll probably be just a data container?
This all depends on your model, in this particular case either one is fine but I'm wondering about what's a good practice.
It's fine to use a class just to store attributes. You may also wish to use a namedtuple instead
The main differences between dict and class are the way you access the attributes [] vs . and inheritence.
instance.__dict__ is just a dict after all
You can even just use a single class for all of those types of objects if you wish
class Bunch:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
movie = Bunch(title='foo', director='bar', ...)
In your case you could use a class that inherits from dict (e.g class MyClass(dict)) so that you can define custom behavior to your dict-like class or use UserDict.
It depends on what you really mean for "perhaps almost no behaviour", if dict already provides what you need stay with it. Otherwise consider to subclass dict adding your specific behaviour. Since Python 2.2 it is possible. Using UserDict is an older approach to the problem.
You could also use a plain dictionary and implement the behaviour externally via some function. I use this approach for prototyping, and eventually refactor the code later to make it Object Oriented (generally more scalable).
You can see what a dictionary offers typing this at the interpreter:
>>> help({})
or referring to the docs.
I would stick to KISS (Keep it simple stupid). If you only want to store values you are better off with a dictionary, because you can dynamically add values at runtime. WRONG:(But you can not add new filds to a class at runtime.)
So classes are useful if they provide state and behaviour.
EDIT: You can add fields to classes in python.

Code design: Instance method with deeply nested conditionals, put in another instance method of the same class or put it in a function?

Suppose I have an instance method that contains a lot of nested conditionals. What would be a good way to encapsulate that code? Put in another instance method of the same class or a function? Could you say why a certain approach is preferred?
If the function is only used by one class, and especially if the module has more classes with potentially more utility functions (used only by one class), it might clarify things a bit if you kept the functions as static methods instead to make it obvious which class they belong to. Also, automated refactorings (using the e.g. the rope library, or PyCharm or PyDev etc) then automatically move the static method along with the class to wherever the class is moved.
P.S. #staticmethods, unlike module-level functions, can be overridden in subclasses, e.g. in case of a mathematical formula that doesn't depend on the object but does depend on the type of the object.
There are two different questions here. The first one is what to do with multiple nested conditionals. There's no single right answer: it depends on your coding style, how the conditions interact, the architecture of your program and so on. Have a look at this Programmers.SE question and Jeff Atwood's blog post for some ideas; personally, I like
if not check1: return
code1
if not check2: return
code 2
...
although some people object to the multiple exit points.
The second question is what to do with individual functions if you're writing object oriented Python. The usual answer is just to put them as functions inside the module containing the class, since there's no requirement that a function be attached to a particular class. If you want, though, you can include them in the class as static methods.

Does type create the class 'Object' in python

I was reading about this excellent post on metaclasses What is a metaclass in Python?. The accepted answer shows how to create a class using type with the following signature.
type(name of the class,
tuple of the parent class (for inheritance, can be empty),
dictionary containing attributes names and values)
That makes me wonder who creates the object class. Is object class also created by type class?
In theory you are correct. object is an instance of type. But, when you check type's base classes, you'll find that type inherits from object! How can this be?
The truth is, this is hard-coded in the Python interpreter. Both object and type are given; neither is actually involved in any way with creating the other.
The main thing to remember at these rarified levels of the object/type hierarchy is that things like object and type are not created in .py files at all, they are created statically in C code, along with the rest of the foundational underpinnings of CPython. So they aren't necessarily "created" with any particular Python code.
type is a bit of a - umm, not sure how to describe it - weirdo of the language.
It can be used to do type(someobj) or used as a constructor (with 3 params) of some sorts to create new types derived from a base with instances. As you have seen with meta-classes - it's useful to make factory classes - although, IMHO unless you really want to be too clever, using class decorators makes this slightly easier in 2.6+

When to use attributes vs. when to use properties in python? [duplicate]

This question already has answers here:
What's the difference between a Python "property" and "attribute"?
(7 answers)
Closed 2 months ago.
Just a quick question, I'm having a little difficulty understanding where to use properties vs. where use to plain old attributes. The distinction to me is a bit blurry. Any resources on the subject would be superb, thank you!
Properties are more flexible than attributes, since you can define functions that describe what is supposed to happen when setting, getting or deleting them. If you don't need this additional flexibility, use attributes – they are easier to declare and faster.
In languages like Java, it is usually recommended to always write getters and setters, in order to have the option to replace these functions with more complex versions in the future. This is not necessary in Python, since the client code syntax to access attributes and properties is the same, so you can always choose to use properties later on, without breaking backwards compatibilty.
The point is that the syntax is interchangeable. Always start with attributes. If you find you need additional calculations when accessing an attribute, replace it with a property.
In addition to what Daniel Roseman said, I often use properties when I'm wrapping something i.e. when I don't store the information myself but wrapped object does. Then properties make excellent accessors.
Properties are attributes + a posteriori encapsulation.
When you turn an attribute into a property, you just define some getter and setter that you "attach" to it, that will hook the data access. Then, you don't need to rewrite the rest of your code, the way for accessing the data is the same, whatever your attribute is a property or not.
Thanks to this very clever and powerful encapsulation mechanism, in Python you can usually go with attributes (without a priori encapsulation, so without any getter nor setter), unless you need to do special things when accessing the data.
If so, then you just can define setters and getters, only if needed, and "attach" them to the attribute, turning it into a property, without any incidence on the rest of your code (whereas in Java, the first thing you usually do when creating a field, usually private, is to create it's associated getter and setter method).
Nice page about attributes, properties and descriptors here

Categories