I'm a bit confused as to how variables (or fields) of classes are handled in python.
I'll give a small example of what I mean.

class Cow: # the first class that popped into my head
    legs = 4

moo = cow()

now,
moo.legs will return 4
and cow.legs will also return 4

Now although legs is a class variable it appears that every object created by Cow has a variable called legs. Wouldn't that make the concept of a class variable obsolete? Why should every object of that class have a variable called legs? If the programmer wanted to do that wouldn't it be more suitable to write an __init__ function such as
self.legs = 4?

try creating your cow like:

class cow:
	numcows = 0
	def __init__(self):
		cow.numcows +=1 
		
		
mycow = cow()
mycow2 = cow()
print cow.numcows
print mycow.numcows
print mycow2.numcows

try creating your cow like:

class cow:
	numcows = 0
	def __init__(self, num):
		cow.numcows +=1 
		self.num = num

print cow.numcows		
		
mycow = cow(13)
print mycow.num
print cow.numcows

mycow2 = cow(23)
print mycow2.num
print cow.numcows
print mycow.numcows
print mycow2.numcows

Edited 7 Years Ago by gerard4143: n/a

Thanks for the examples.. (and accepting that I chose to use "cow"). They really helped. Problem solved.

Is it good programming practice to refer to class variables by using their instances?
like mycow.numcows?

Is it good programming practice to refer to class variables by using their instances?
like mycow.numcows?

Yes it's good programming practice. The purpose of classes is to hold data shared by all the instances of the class. This includes class variables, also called static fields in other languages.

To make more sense you should have written your class this way:

class Animal:
    def __init__(self, legs):
        self.legs = legs
        
cow = Animal(4)
chicken = Animal(2)
octopus = Animal(8)
# Bob is a pet chicken with 1 leg missing
bob = Animal(1)

print( octopus.legs )  # 8
print( chicken.legs )  # 2

Yes it's good programming practice. The purpose of classes is to hold data shared by all the instances of the class. This includes class variables, also called static fields in other languages.

is that where the command / statement "staticmethod" in python comes from?

is that where the command / statement "staticmethod" in python comes from?

Yes. It came from older OO languages like C++.

Just to have some fun i build on sneekula Animal class.
Here the animal has name and it can eat and poop.

class Animal(object):
    def __init__(self, name, legs):
        self.name = name
        self.legs = legs
        self.stomach = []        
        
    def __call__(self,food):
        self.stomach.append(food)
    
    def poop(self):
        if len(self.stomach) > 0:
            return self.stomach.pop(0)
        
    def __str__(self):        
        return 'A animal named %s' % (self.name)        
        
        
cow = Animal('king', 4)
dog = Animal('flopp', 4)
print 'We have 2 animales a cow name %s and dog named %s,both have %s legs' % (cow.name, dog.name, cow.legs)
print cow  #here __str__ metod work

#We give food to cow
cow('gras')
print cow.stomach

#We give food to dog
dog('bone')
dog('beef')
print dog.stomach

#What comes inn most come out
print cow.poop()
print cow.stomach  #Empty stomach

''' output-->
We have 2 animales a cow named king and dog named flopp,both have 4 legs
A animal named king
['gras']
['bone', 'beef']
gras
[]
'''

Edited 7 Years Ago by snippsat: n/a

Is it good programming practice to refer to class variables by using their instances?
like mycow.numcows?

There are times that referring by self is the way to go.

If you use self.somevar python first looks if there is a member variable named somevar .
If not found: look for a class variable with that name self.__class__.somevar .
If not found: look for parent class variables named somevar .
If not found: report an error.

You use this when there is a setting for a class but you want to overrule it for a specific instance. By assigning self.classvarname = .... in some method of the class you use a different value for this instance.

class example(object):
    BOLD = True
    def dump(self,*args):
        if self.BOLD:
            pass
    def setBold(self,bold):
        self.BOLD = bold  # overrule the class setting for this object
This question has already been answered. Start a new discussion instead.