Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I have started to learn Python OOP today.
Kindly, take a look at the following class, and its usage:
class MyClass:
pass
obj1 = MyClass()
obj1.x = 10
obj1.y = "Integer"
obj2 = MyClass()
obj2.a = 20.5
obj2.b = "Floating point"
print(obj1.x)
print(obj1.y)
print(obj2.a)
print(obj2.b)
Output
10
Integer
20.5
Floating point
Python allows creation of properties on the fly
different objects are allowed to have different properties
According to OOP principle, properties should be private. But, I am seeing that, in Python, properties are freely accessible from outside class
We know that class is a blue-print of objects. But, in this case, we see that, every object is different.
So, how is Python following OOP principle?
Python is rather more flexible than most languages. Class definitions don't impose any particular structure; they just provide a mechanism for method calls, inheritance, etc. You need to define an appropriate __init__ method to abstract the details of how an object should "look".
class MyClass:
def __init__(self, x, y):
self.x = x
self.y = y
obj1 = MyClass(10, "Integer")
obj2 = MyClass(20.5, "Floating point")
Now both objects have x and y attributes, because you let the class take care of setting them, rather than creating them yourself.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Below two variants to initialize a class instance variable. What is the best practice for initializing an instance variable in a class in python and why (maybe none of the suggested variants)?
Assumption: variant a because it might be more explicit?
class Example():
def __init__(self, parameter):
# EITHER
# variant a to initialize var_1
self.var_1 = self.initialize_var_1_variant_a(parameter)
# OR
# variant b to initialize var_1
self.initialize_var_1_variant_b(parameter)
# OR something else
# ...
def initialize_var_1_variant_a(self, parameter):
# complex calculations, var_1 = f(parameter)
result_of_complex_calculations = 123
return result_of_complex_calculations
def initialize_var_1_variant_b(self, parameter):
# complex calculations, var_1 = f(parameter)
result_of_complex_calculations = 123
self.var_1 = result_of_complex_calculations
example_instance = Example("some_parameter")
print(example_instance.var_1)
Variant A is the common way to do this. It is very nice to be able to see all of the class members by looking at __init__, instead of having to dive into the other functions (initialize_var_1_variant_b) to find out exactly what attributes are set.
In general, all member attributes that a class will ever have should be initialized in __init__.
To come at it from another angle, initialize_var_1_variant_a should do as little as possible. Calculating the value of var_1 and saving it as a class attribute are two tasks that can be easily broken apart.
It also opens up the possibility of moving initialize_var_1_variant_a outside of the class itself, so it could be re-used by other parts of your program down the line.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
If I have an object, and within that object I've defined a variable, which of these methods would be considered 'best' for accessing the variable?
Method One
Using a getter function
class MyClass:
def __init__(self):
self.the_variable = 21 * 2
def get_the_variable(self):
return self.the_variable
if __name__ == "__main__"
a = MyClass()
print(a.get_the_variable())
Method Two
Using the #property decorator
class MyClass:
def __init__(self):
self._the_variable = 21 * 2
#property
def the_variable(self):
return self._the_variable
if __name__ == "__main__"
a = MyClass()
print(a.the_variable)
Method Three
Simply accessing it directly
class MyClass:
def __init__(self):
self.the_variable = 21 * 2
if __name__ == "__main__"
a = MyClass()
print(a.the_variable)
Are any of these methods more pythonic than the others?
Method 3 is the standard pythonic way to start. If you need additional logic, filtering or some other behavior for the attribute you can always go back and add a method for the attribute and use the #property decorator at a later time. That's the beauty of python, start with something simple that works. If you later need finer control over the attribute you can create the property and not have to update/change any of the client code that uses the attribute. The client code will not know the difference between accessing the attribute directly vs calling a method and as a result does not have to change.
This ideology is confirmed via PEP 549
Python's descriptor protocol guides programmers towards elegant API design. If your class supports a data-like member, and you might someday need to run code when changing the member's value, you're encouraged to simply declare it as a simple data member of the class for now. If in the future you do need to run code, you can change it to a "property", and happily the API doesn't change.
I think it's not easy to answer since it's based on the program.
class MyClass:
def __init__(self):
self.the_variable = 21 * 2
def get_the_variable(self):
return self.the_variable
But if you want to pass a class attirubete to some variable, I think it's better to use getter-setter, since it is more readable and understandable. Because you are basically telling I ask this value. For example:
if __name__ == "__main__":
a = MyClass()
modified_variable = a.get_the_variable() * 2
In contrary, if you are just using that class attribute, third option a.the_variable is better.
if a.get_the_variable() == 42:
# do something
else:
# do something
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I want to create a service class that just has one instance, so should I make that class a singleton, or should I make the methods as classmethods?
class PromoService():
#classmethod
def create_promo(cls, promotion):
#do stuff
return promo
class DiscountPromoService(PromoService):
#classmethod
def create_promo(cls, promo, discount):
promo = super(DiscountPromoService, cls).create_promo(promo)
promo.discount = discount
promo.save()
return promo
The reason I don't want to create it as a module is because I would need to subclass my service. What is the most pythonic way to do this, the above-mentioned way or to make a singleton class?
Short answer: In my opinion it would work.
BUT, In pure pattern's sense, I have been wrestling with this question for a while:
Do python class methods and class attributes essentially behave like a Singleton?
All instances of that class have no bearing on them
Only class itself have access to them
There is always one of them
Yes, pure Singleton Pattern comparison would fail plain and simple but surely its not far off?
Wouldn't call myself a python expert, so happy to know views on this be corrected on my assumptions.
If you want a singleton, go with a singleton. The pattern referenced here works well. You would simply need to do something like:
class PromoService():
__metaclass__ = Singleton
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I've been reading through Numpy's documentation standards, and it doesn't seem to make a mention of object attributes - only class attributes.
So, for instance, how would I document the following?
class ClassA(object):
"""Short description of ClassA
Long description of ClassA
Parameters
----------
param : param_type, optional
param_description
Attributes (class)
----------
class_attr : class_attr_type
class_attr_description
Attributes (object)
----------
obj_attr : obj_attr_type
obj_attr_description
"""
class_attr = 'something'
def __init__(self, arg='something else'):
self.obj_attr = arg
EDIT:
Just wanted to note that I'm switching to Napoleon, which says it supports attributes, but not specifically class or instance attributes.
I tried what is mentioned in the How to Document file provided in numpy. It mentions the documentation of class attributes should be handled as follows.
An Attributes section, located below the Parameters section, may be used to describe class variables:
Attributes
----------
x : float
The X coordinate.
y : float
The Y coordinate.
It goes on to mention that instance properties should have their own documentation and only be listed by name.
That makes sense but I can't find any examples of this in the numpy source code. The closest I found did something different in ABCPolyBase class.
Attributes
----------
coef : (N,) ndarray
...
Class Attributes
----------------
maxpower : int
In my opinion, the documentation used in the _polybase.py class is legible but I do not believe the Class Attributes usage will work with Sphinx autodoc summaries.
I hope this information is helpful.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
I am trying to implement this in the new style class and failing. In this example I want to create forests with different populations of plants and animals.
class forest:
def __init__(self,p,a):
self.alive="alive"
self.pl = []
self.ani = []
for i in range(p):
self.pl.append(self.Plant())
for i in range(a):
self.ani.append(self.Animal())
class Plant:
def __init__(self):
self.synth = "co2"
self.name = "coconut"
class Animal:
def __init__(self):
self.carb="o2"
self.name="orangutan"
Edit:
As Lazlow requested.
My problem was that I was confused between nesting and inheritance.
so in my approaches I was trying to do this
class forest(object):
....
....
class Plant(forest):
instead of using class Plant(object). I was also trying to define functions which should have been in forest class in Plant class. I was trying to use /super/ keyword to achieve things which I should no have. I was then lost in reading about creating descriptors to do what I wanted. I assumed that all of these attempts would distract from the problem I had. They were instantly cleared after I read the first response.
My thanks to both of you.
Regards,
abcd
The difference between old-style class declarations and new-style ones is that new-style classes must inherit from object (or some other new-style class). So, to make your classes new-style, just put (object) after the class name:
class forest(object):
# ...
You're also nesting classes, which isn't forbidden in either new or old-style classes, but which is often confusing and unnecessary. Just unindent your Plant and Animal class declarations and you should be fine. You can make them new-style too, if you want, by inheriting from object.
Note that if you're using Python 3, all classes are new-style classes. You don't need to explicitly inherit from object, as the compiler will add that for you if you omit it. It's often a good idea to make it explicit, especially if you use both Python 2 and Python 3 at different times.