I have many Questions !
look at this code plz:
class Dog(object):
_the_most_oldest = int()
def __init__(self,age):
self.age=age
#staticmethod
#property
def the_most_oldest(age):
if Dog._the_most_oldest < age:
Dog._the_most_oldest=age
return Dog._the_most_oldest
1 :
is it maybe that a property be a static method ??
beacuse I need a really static var that share between instances -> _the_most_oldest dog ! => so I need #property . and because the_most_oldest(age) method is not for any special instance I need #staticmethod !
2 :
the second thing I need to do is in every instace the_most_oldest shuold be call and calculate and refresh _the_most_oldest var. how do that ?
this have Error :
def __init__(self,age):
self.age=age
the_most_oldest(self.age)
No, property can not be static method (it's not a method it's descriptor).
Create class attribute which will hold all instances of that class.
class Dog(object):
_dogs = []
And put new instances in the _dogs class attribute.
def __init__(self, age):
self._dogs.append(self)
self.age = age
And then create classmethod the_most_oldest. Which will calculate the most oldest dog of all instances.
#classmethod
def the_most_oldest(cls):
return max(cls._dogs, key=lambda dog: dog.age)
In your place I would initialize _the_most_oldest = 0 (and maybe call it _the_oldest, better english)
A #staticmethod in Python is just a function "contained in a class" in your case I think it would be better to use #classmethod.
If you want to assign a value to a property you can not use the decorator, you need to pass a setter and a getter method.
def _get_oldest(self):
return self._the_oldest
def _set_oldest(self, age):
if Dog._the_oldest < age:
Dog._the_oldest=age
the_oldest = property(_get_oldest, _set_oldest)
Related
I would like to replace an object instance by another instance inside a method like this:
class A:
def method1(self):
self = func(self)
The object is retrieved from a database.
It is unlikely that replacing the 'self' variable will accomplish whatever you're trying to do, that couldn't just be accomplished by storing the result of func(self) in a different variable. 'self' is effectively a local variable only defined for the duration of the method call, used to pass in the instance of the class which is being operated upon. Replacing self will not actually replace references to the original instance of the class held by other objects, nor will it create a lasting reference to the new instance which was assigned to it.
As far as I understand, If you are trying to replace the current object with another object of same type (assuming func won't change the object type) from an member function. I think this will achieve that:
class A:
def method1(self):
newObj = func(self)
self.__dict__.update(newObj.__dict__)
It is not a direct answer to the question, but in the posts below there's a solution for what amirouche tried to do:
Python object conversion
Can I dynamically convert an instance of one class to another?
And here's working code sample (Python 3.2.5).
class Men:
def __init__(self, name):
self.name = name
def who_are_you(self):
print("I'm a men! My name is " + self.name)
def cast_to(self, sex, name):
self.__class__ = sex
self.name = name
def method_unique_to_men(self):
print('I made The Matrix')
class Women:
def __init__(self, name):
self.name = name
def who_are_you(self):
print("I'm a women! My name is " + self.name)
def cast_to(self, sex, name):
self.__class__ = sex
self.name = name
def method_unique_to_women(self):
print('I made Cloud Atlas')
men = Men('Larry')
men.who_are_you()
#>>> I'm a men! My name is Larry
men.method_unique_to_men()
#>>> I made The Matrix
men.cast_to(Women, 'Lana')
men.who_are_you()
#>>> I'm a women! My name is Lana
men.method_unique_to_women()
#>>> I made Cloud Atlas
Note the self.__class__ and not self.__class__.__name__. I.e. this technique not only replaces class name, but actually converts an instance of a class (at least both of them have same id()). Also, 1) I don't know whether it is "safe to replace a self object by another object of the same type in [an object own] method"; 2) it works with different types of objects, not only with ones that are of the same type; 3) it works not exactly like amirouche wanted: you can't init class like Class(args), only Class() (I'm not a pro and can't answer why it's like this).
Yes, all that will happen is that you won't be able to reference the current instance of your class A (unless you set another variable to self before you change it.) I wouldn't recommend it though, it makes for less readable code.
Note that you're only changing a variable, just like any other. Doing self = 123 is the same as doing abc = 123. self is only a reference to the current instance within the method. You can't change your instance by setting self.
What func(self) should do is to change the variables of your instance:
def func(obj):
obj.var_a = 123
obj.var_b = 'abc'
Then do this:
class A:
def method1(self):
func(self) # No need to assign self here
In many cases, a good way to achieve what you want is to call __init__ again. For example:
class MyList(list):
def trim(self,n):
self.__init__(self[:-n])
x = MyList([1,2,3,4])
x.trim(2)
assert type(x) == MyList
assert x == [1,2]
Note that this comes with a few assumptions such as the all that you want to change about the object being set in __init__. Also beware that this could cause problems with inheriting classes that redefine __init__ in an incompatible manner.
Yes, there is nothing wrong with this. Haters gonna hate. (Looking at you Pycharm with your in most cases imaginable, there's no point in such reassignment and it indicates an error).
A situation where you could do this is:
some_method(self, ...):
...
if(some_condition):
self = self.some_other_method()
...
return ...
Sure, you could start the method body by reassigning self to some other variable, but if you wouldn't normally do that with other parametres, why do it with self?
One can use the self assignment in a method, to change the class of instance to a derived class.
Of course one could assign it to a new object, but then the use of the new object ripples through the rest of code in the method. Reassiging it to self, leaves the rest of the method untouched.
class aclass:
def methodA(self):
...
if condition:
self = replace_by_derived(self)
# self is now referencing to an instance of a derived class
# with probably the same values for its data attributes
# all code here remains untouched
...
self.methodB() # calls the methodB of derivedclass is condition is True
...
def methodB(self):
# methodB of class aclass
...
class derivedclass(aclass):
def methodB(self):
#methodB of class derivedclass
...
But apart from such a special use case, I don't see any advantages to replace self.
You can make the instance a singleton element of the class
and mark the methods with #classmethod.
from enum import IntEnum
from collections import namedtuple
class kind(IntEnum):
circle = 1
square = 2
def attr(y): return [getattr(y, x) for x in 'k l b u r'.split()]
class Shape(namedtuple('Shape', 'k,l,b,u,r')):
self = None
#classmethod
def __repr__(cls):
return "<Shape({},{},{},{},{}) object at {}>".format(
*(attr(cls.self)+[id(cls.self)]))
#classmethod
def transform(cls, func):
cls.self = cls.self._replace(**func(cls.self))
Shape.self = Shape(k=1, l=2, b=3, u=4, r=5)
s = Shape.self
def nextkind(self):
return {'k': self.k+1}
print(repr(s)) # <Shape(1,2,3,4,5) object at 139766656561792>
s.transform(nextkind)
print(repr(s)) # <Shape(2,2,3,4,5) object at 139766656561888>
I'm designing one class for common library.
This class method called sequencially like below.
call order is 'class method' -> 'instance method' -> 'instance method'
I don't know why last instance method need self parameter..
Ordinally instance method does not need self method as we know.
What am I missing?
class A:
#classmethod
def first(cls):
print('cls method')
cls.second(cls)
def second(self):
print('inst method 1')
self.third(self) # Question! Why this method need [self] parameter?
def third(self):
print('inst method 2')
A.first()
It's because of how you're calling second.
Say you have such a class:
class A:
def do_thing(self):
pass
The following are equivalent:
a = A()
a.do_thing()
A.do_thing(a)
In other words, when we call a method of an instance, it is the same as looking up a function attribute of the class object and calling it with that instance as the first argument.
Now, note that when you call second, you pass cls to it. That is the class object and not an instance, which means that you're doing something like A.do_thing. Therefore, for it to know which instance you want to call third on, you need to pass in self.
The only thing you're missing out is that you're not creating an instance for your class.
Try this-
class A:
#classmethod
def first(cls):
print('cls method')
cls.second(cls)
def second(self):
print('inst method 1')
self.third(self)
def third(self):
print('inst method 2')
instance = A()
instance.first()
This should give you your desired output. As for why the last method needs self as a parameter, self refers to the instance that you're applying the method on, and thus you can change it's properties with it. Let me give you an example-
class Kid():
def __init__(self, name, age):
self.name = name
self.age = age
def change_age(self, age):
self.age = age
tom = Kid('Tom', 13)
print(tom.age) #prints 13
tom.change_age(14)
print(tom.age) #prints 14
Here, with the self argument in the method, Python would know which instances' property age does it have to change.
In your use case, it might seem not to make much sense though. I hope this helps. :)
Just curious,
Is it possible to keep static attrs in a class that returns instantiated objects for the same class? Specifically not using a factory method but attr
class Money:
CENT = Money('cent')
def __init__(self, value):
self.value = value
Money.CENT #==> Returns Money('cent')
The best I could come up with is, But not within the same class.
class SampleMoney:
CENT = Money('cent')
DOLLAR = Something('dollar')
SampleMoney.CENT #==> Money('cent')
You could use the following hack to create a class property:
class Something:
class __metaclass__:
#property
def EMPTY(cls):
return cls('empty')
Alternatively, just define it after?
class Something:
# ...
Something.EMPTY = Something('empty')
I am trying to assign a method's return to a variable and stuck with this error.
class MyClass():
def my_def(self):
return "Hello"
my_variable = my_def()
Here is the Java equivalent of what I want to do.
public class NewException {
public int method1(){
return 1;
}
public int variable = method1();
}
I am sure this is something simple, but I couldn't even find the right words to google this. Any help is appreciated.
Lets start with the difference between methods and functions, basically a method belongs to some object while a function does not. So for example
def myFunction():
return "F"
class MyClass:
value = 0
def myMethod(self, value):
old = self.value
self.value = value
return old
myClassInstance = MyClass()
print myClassInstance.myMethod(3)
# 0
print myClassInstance.myMethod(33)
# 3
print myFunction()
# F
Notice that the method is bound to the instance and it doesn't make sense to call the method before the instance is created. With that in mind, your error should make more sense. The method cannot be called without an instance (self). This is not the only kind of method, for example there are "static methods". Static methods are defined on the class, but they are called without an instance. For example:
class MyClass:
#staticmethod
def myStaticMethod():
return "static method"
# Consider using an instance attribute instead of a class attribute
def __init__(self):
self.instance_attribute = MyClass.myStaticMethod()
# Or if you need a class attribute it needs to go outside the class block
MyClass.class_attribute = MyClass.myStaticMethod()
Im having some trouble understanding Inheritance in classes and wondering why this bit of python code is not working, can anyone walk me through what is going wrong here?
## Animal is-a object
class Animal(object):
def __init__(self, name, sound):
self.implimented = False
self.name = name
self.sound = sound
def speak(self):
if self.implimented == True:
print "Sound: ", self.sound
def animal_name(self):
if self.implimented == True:
print "Name: ", self.name
## Dog is-a Animal
class Dog(Animal):
def __init__(self):
self.implimented = True
name = "Dog"
sound = "Woof"
mark = Dog(Animal)
mark.animal_name()
mark.speak()
This is the output through the terminal
Traceback (most recent call last):
File "/private/var/folders/nd/4r8kqczj19j1yk8n59f1pmp80000gn/T/Cleanup At Startup/ex41-376235301.968.py", line 26, in <module>
mark = Dog(Animal)
TypeError: __init__() takes exactly 1 argument (2 given)
logout
I was trying to get animal to check if an animal was implemented, and then if so, get the classes inheriting from animal to set the variables that Animals would then be able to manipulate.
katrielalex answered your question pretty well, but I'd also like to point out that your classes are somewhat poorly - if not incorrectly - coded. There seems to be few misunderstandings about the way you use classes.
First, I would recommend reading the Python docs to get the basic idea: http://docs.python.org/2/tutorial/classes.html
To create a class, you simply do
class Animal:
def __init__(self, name, sound): # class constructor
self.name = name
self.sound = sound
And now you can create name objects by calling a1 = Animal("Leo The Lion", "Rawr") or so.
To inherit a class, you do:
# Define superclass (Animal) already in the class definition
class Dog(Animal):
# Subclasses can take additional parameters, such as age
def __init__(self, age):
# Use super class' (Animal's) __init__ method to initialize name and sound
# You don't define them separately in the Dog section
super(Dog, self).__init__("Dog", "Woof")
# Normally define attributes that don't belong to super class
self.age = age
And now you can create a simple Dog object by saying d1 = Dog(18) and you don't need to use d1 = Dog(Animal), you already told the class that it's superclass is Animal at the first line class Dog(Animal):
To create an instance of a class you do
mark = Dog()
not mark = Dog(Animal).
Don't do this implimented stuff. If you want a class that you can't instantiate (i.e. you have to subclass first), do
import abc
class Animal(object):
__metaclass__ = abc.ABCMeta
def speak(self):
...
Since age in the given example is not part of the parent (or base) class, you have to implement the the function (which in a class is called method) in the class which inheritted (also known as derived class).
class Dog(Animal):
# Subclasses can take additional parameters, such as age
def __init__(self, age):
... # Implementation can be found in reaction before this one
def give_age( self ):
print self.age