Skip to main content
GameDev.net gamedev.net
🔒 Locked

Python Immutable member variables?

Started by Tutorial Doctor Jul 2, 2015 at 5:58 PM 6 replies 4.9k views
Original Post
Tutorial Doctor
Tutorial Doctor

I have been trying to create a sample script for inheritance in Python, but I don't know how to make a member variable for a class immutable.

In the following code, I want the symbol of the object to not be able to be changed.


#How to make member variables permanent?
#Customizing class creation 3.4.3
#print '#'+'-'*79
#Tutorial Doctor 5/28/15
#------------------------------------------------------------------------------


#CLASSES
#------------------------------------------------------------------------------
class Human(object):
	def __init__(self,name='N/A',age=0):
		stages=['null','infant','toddler','?','adolescent','adult']
		self.name = name
		self.age=age
		self.stage=stages[0]
		
		if self.age<=2:
			self.stage=stages[1]
		elif self.age<=5:
			self.stage=stages[2]
		elif self.age<18 and self.age >=13:
			self.stage=stages[4]
		elif self.age>=18:
			self.stage=stages[5]
		else:
			self.stage=stages[3]
		
	
class Female(Human):
	#This is the init function for the present class
	def __init__(self,name='Female',age=0):
		#Loading the init function for the inherited class and whichever variables you want to inherit
		Human.__init__(self,name,age)
		#Adding more variables
		self.SYMBOL = 'o+'


class Male(Human):
	def __init__(self,name='Male',age=0):
		Human.__init__(self,name,age)
		self.SYMBOL='o->'


class Woman(Female):
	def __init__(self,name='Woman',age=18):
		Female.__init__(self,name,age)


class Girl(Female):
	def __init__(self,name='Girl',age=0):
		Female.__init__(self,name,age)
		
		
class Man(Male):
	def __init__(self,name='Man',age=18):
		Male.__init__(self,name,age)


class Boy(Male):
	def __init__(self,name='Boy',age=0):
		Male.__init__(self,name,age)
#-------------------------------------------------------------------------------


#INSTANTIATION
#-------------------------------------------------------------------------------
human=Human()
print human.name
print human.age

print

sarah=Woman('Sarah',35)
print sarah.name
print sarah.SYMBOL
print sarah.age
print sarah.stage

print

joey=Man('Joey',17)
print joey.name
print joey.SYMBOL
print joey.age
print joey.stage

billy = Boy('Bill',1)
print billy.stage + " is billy's stage"

jill = Girl('Jill',5)
print jill.stage + " is jill's stage"
#------------------------------------------------------------------------------


#FUNCTIONS
#------------------------------------------------------------------------------
#Returns True if input is a male
def is_male(x):
	if x.SYMBOL=='o->':
		return True
	return False

#Returns True if input is a female
def is_female(x):
	if x.SYMBOL=='o+':
		return True
	return False

print

print is_male(sarah)
print is_male(joey)
print is_female(sarah)

if is_female(sarah):
	print sarah.name + ' is old enough.'
#------------------------------------------------------------------------------


#
#------------------------------------------------------------------------------
print Human.__subclasses__()
print
print sarah.__class__()
print
print dir()
print
print dir(Man)

How would I do this in Python?

They call me the Tutorial Doctor.
TheComet
TheComet

Basically, python doesn't have anything that can make a variable immutable. While there are immutable types, one can always mutate the variable referencing said type.

http://stackoverflow.com/questions/8056130/immutable-vs-mutable-types-python

The best approach here would be to make your member variable private (by prefixing two underscores) and adding a getter:


class Human(object):
    def __init__(self, symbol):
        self.__symbol = symbol
    def get_symbol(self):
        return self.__symbol


class Female(Human):
    def __init__(self):
        super(Female, self).__init__('o+')


if __name__ == '__main__':
    f = Female()
    print(f.get_symbol())
"I would try to find halo source code by bungie best fps engine ever created, u see why call of duty loses speed due to its detail." -- GettingNifty
TheComet
TheComet

See also property()

Oh neat, I didn't know about that. Thanks!

"I would try to find halo source code by bungie best fps engine ever created, u see why call of duty loses speed due to its detail." -- GettingNifty
Oluseyi
Oluseyi

See also property()


Yep, the closest thing to immutability in Python is a property member with a setter that does nothing.

Note that even access control doesn't really exist in Python; you can always introspect the object to determine all of its members. The double leading underscore just excludes it from default name resolution, but dumping the object dictionary shows it plain as day.

ChaosEngine
ChaosEngine

Yep, the closest thing to immutability in Python is a property member with a setter that does nothing.


Well, in version 3 you don't even need a setter


>>> class Test:
	def __init__(self, x):
		self.__x = x
	@property
	def X(self):
		return self.__x

>>> t = Test(2)
>>> t.X
2
>>> t.X = 4
Traceback (most recent call last):
  File "<pyshell#14>", line 1, in <module>
    t.X = 4
AttributeError: can't set attribute

Note that even access control doesn't really exist in Python; you can always introspect the object to determine all of its members. The double leading underscore just excludes it from default name resolution, but dumping the object dictionary shows it plain as day.

yep, and you can modify it too


>>> t.__dict__
{'_Test__x': 2}
>>> t._Test__x = 3
>>> t.X
3
if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
Tutorial Doctor
Tutorial Doctor

Thanks. I will check all of this out.

They call me the Tutorial Doctor.
Oluseyi
Oluseyi

Yep, the closest thing to immutability in Python is a property member with a setter that does nothing.


Well, in version 3 you don't even need a setter


>>> class Test:
	def __init__(self, x):
		self.__x = x
	@property
	def X(self):
		return self.__x

>>> t = Test(2)
>>> t.X
2
>>> t.X = 4
Traceback (most recent call last):
  File "<pyshell#14>", line 1, in <module>
    t.X = 4
AttributeError: can't set attribute 

Yep, though I wanted to address the underlying mechanism first before tackling attribute-based syntactic sugar, but you're absolutely right.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.