This question already has answers here:
Python method name with double-underscore is overridden?
(2 answers)
Closed 6 years ago.
I'm confused with the class attribute. I understand that Python interpreter will search attr inside cls.__dict_ (object attribute) first, If the attribute doesn't exists, it will looking for at class attributes. But in that case I dont know why the result below return None
class A(object):
__attr = None
#property
def attr(self):
return self.__attr
class B(A):
__attr = 1
c = B()
print(c.attr)
# None
This isn't about property, but about the behaviour of attributes prefixed with __. This triggers name mangling, which is almost never what you want and behaves unexpectedly in an inheritance scenario. Don't use it.
Related
This question already has answers here:
How do you change the value of one attribute by changing the value of another? (dependent attributes)
(1 answer)
Call Python Method on Class Attribute Change
(2 answers)
Detecting class attribute value change and then changing another class attribute
(1 answer)
Closed 2 years ago.
For example, I have a class:
import datetime
class Obj:
def __init__(self, attribute_1):
self.attribute_1 = attribute_1
self.last_edited = None
I want it to be able to do this:
# Creating object
obj1 = Obj("a")
obj1.attribute_1 = "b" # obj1.last_edited should have changed to datetime.datetime.now()
I'm not sure how to implement the changing of obj1's 'last_edited' attribute if I were to directly change obj1's 'attribute_1' (without any setters).
Thanks in advance.
All Python objects have a builtin method called __setattr__ that is called whenever a field in the class is changed. This method by default updates a value in the class dictionary (stored internally to represent the state of a class instance). You can override this behavior by defining a custom __setattr__ method. For your use case, the function might look like this:
class SomeObject:
def __init__(self, attr):
self.attr = attr
def __setattr__(self, name, value):
super().__setattr__("last_edited", time.time())
super().__setattr__(name, value)
Notice that we need to use a super call to avoid recursion (use the __setattr__ method of the base object class).
This question already has answers here:
What is the purpose of the `self` parameter? Why is it needed?
(26 answers)
Closed 3 years ago.
class First:
#classmethod
def hello(self):
print(123)
class Second:
#classmethod
def hello(cls):
print(123)
obj1 = First()
obj2 = Second()
print(obj1.hello())
print(obj1.hello())
I am not getting any error while calling obj1 (with self as argument) and obj2 (with cls as argument). Why not? Is the classmethod decorator able to use cls/self?
One will be understood by every reasonably experienced Python programmer.
The other one will confuse every reasonably experienced Python programmer.
The first argument of a classmethod is a class and should be called cls. You can give it any other name in your code, but that's a bad idea, because it still is a class.
This question already has answers here:
How does the #property decorator work in Python?
(15 answers)
How do Python properties work?
(4 answers)
Closed 4 years ago.
I can do
class Foo(object):
x = property(lambda _: 123)
f = Foo()
f.x
to get 123
However, if I try
p = property(lambda : 123)
p
I get
<property object at 0x108f2f3b8>
Now I understand that an member of a class instance is not the same thing as a regular variable but I'm not sure what exactly makes this behavior different.
Does the fact that you instantiate a class somehow do extra binding on property objects? Is it a special case or is it a behavior I can take advantage in other situations and extend? Related - are property objects useful outside of a class declaration? Or is it just for this specific case?
This question already has answers here:
How to get the caller class name inside a function of another class in python?
(6 answers)
Closed 7 years ago.
class MyClass:
def my_method(self):
print(get_context())
MyClass().my_method()
I need get next line:
MyClass::my_method
sys._getframe(2).f_code.co_name gives me only "my_method". How to get also class name?
You can get your classname by calling __class__.__name__ from self.
class Foo(object):
def bar(self):
print(self.__class__.__name__)
Foo().bar()
Output:
Foo
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between #staticmethod and #classmethod in Python?
I am learning OOP in python and came to know about these two methods
It seems that the difference in terms of syntax is that class methods are implicitly passed the class they belong to as their first parameter
class Circle:
all_circles = [] # class variable
#staticmethod
def total_area():
for c in Circle.all_circles: # hardcode class name
# do somethig
#classmethod
def total_area(cls):
for c in cls.all_circles: # no hardcode class name
# do something
I see class method as more flexible since we don't hardcode the class
Question:
- Is it even a question which one is better? #staticmethod or #classmethod?
- what are the scenarios suitable to use of each one of these methods?
A classmethod gets passed the class 'cls' that it was called upon. For more details see: What is the difference between #staticmethod and #classmethod in Python?