Turinys

Klasės

Teorija

In C++ terminology, all class members (including the data members) are public, and all member functions are virtual. There are no special constructors or destructors.

As in Smalltalk, classes themselves are objects, albeit in the wider sense of the word: in Python, all data types are objects.

<…>

A namespace is a mapping from names to objects. <…> Examples of namespaces are: the set of built-in names (functions such as abs(), and built-in exception names); the global names in a module; and the local names in a function invocation.

<…>

By the way, I use the word attribute for any name following a dot – for example, in the expression z.real, real is an attribute of the object z. Strictly speaking, references to names in modules are attribute references: in the expression modname.funcname, modname is a module object and funcname is an attribute of it.

<…>

<…>

A scope is a textual region of a Python program where a namespace is directly accessible. „Directly accessible“ here means that an unqualified reference to a name attempts to find the name in the namespace.

<…>

A special quirk of Python is that assignments always go into the innermost scope. Assignments do not copy data – they just bind names to objects. The same is true for deletions: the statement „del x“ removes the binding of x from the namespace referenced by the local scope. In fact, all operations that introduce new names use the local scope: in particular, import statements and function definitions bind the module or function name in the local scope. (The global statement can be used to indicate that particular variables live in the global scope.)

<…>

Data attributes override method attributes with the same name; to avoid accidental name conflicts, which may cause hard-to-find bugs in large programs, it is wise to use some kind of convention that minimizes the chance of conflicts.

Paprasta klasė

class Kalkuliatorius:
	"Kalkuliatoriaus klasė"
 
	bandymas = 0
 
	# Eulerio konstanta
	e = 2.71828182845904523536
 
	# 'self' naudojamas, kai reikia pasinaudoti to pačio objekto metodais/duomenimis, ir yra perduodamas kiekvienam metodui
	def sudetis (self, x, y): return x+y
	def atimtis (self, x, y): return x-y
	def daygyba (self, x, y): return x*y
	def dalyba (self, x, y):
		try:
			x/y
		except ZeroDivisionError:
			print "Dalyba iš nulio negalima!"
			raise
 
	def laipsnis (self, skaichius, laipsnis):
		"Pakelia skaičių laipsniu"
 
		# Paverčiame float'u
		skaichius = float(skaichius)
 
		# Jeigu laipsnis neigiamas
		if (laipsnis < 0):
			laipsnis = -1 * laipsnis
			skaichius = 1 / skaichius
 
		# Apskaičiuojame laipsnį
		rezultatas = skaichius
		for x in range(1,laipsnis):
			rezultatas = rezultatas * skaichius
 
		# Grąžiname rezultatą
		return rezultatas
 
	def kv_shaknis (self, skaichius):
		"Iš skaičiaus ištraukia kvadratinę šaknį"
 
		# Paverčiame float'u
		skaichius = float(skaichius)
 
		# sqrt(x) = e^(1/2 * ln x)
 
		# Tingiu galvoti
		return 3
 
 
	def ln (self, skaichius):
		"Apskaičiuoja naturalųjį skaičiaus logaritmą"
 
	# A la contructor'ius
	def __init__ (self):
		self.bandymas = 12345
 
# Kuriame klasės objektą
k = Kalkuliatorius()
 
print k.bandymas # 12345
print k.sudetis (3, 4) # 7
print k.laipsnis (2, -2)
print k.kv_shaknis (9)

Paveldėjimai klasėse

Paveldėti galimą vieną klasę arba daugiau (tada paveldimas klases reikia atskirti kableliais).

class Krutesnis_kalkuliatorius (Kalkuliatorius):
	def kruta_funkcija (self):
		print "Ash esu kruta funkcija"
		print "2 + 2 =", self.sudetis (2, 2) # 4
		print "2 * 2 =", self.daugyba (2, 3) # 8 ;-)
 
	# Override'inama funkcija
	def daugyba (self, a, b): return (a*b)+2
 
	# Privatus kintamasis (nebus pasiekiamas ne ish klases ir nebus paveldimas)
	__niekas_shito_nemato = 3
 
k2 = Krutesnis_kalkuliatorius()
k2.kruta_funkcija ()

Klasė, panaudojama "for" loop'ui

class Reverse:
	"Iterator for looping over a sequence backwards"
	def __init__(self, data):
		self.data = data
		self.index = len(data)
	def __iter__(self):
		return self
	def next(self):
		if self.index == 0:
			raise StopIteration
		self.index = self.index - 1
		return self.data[self.index]
 
for char in Reverse('spam'):
	print char # maps

Generatoriai

Generators are a simple and powerful tool for creating iterators. They are written like regular functions but use the yield statement whenever they want to return data. Each time next() is called, the generator resumes where it left-off (it remembers all the data values and which statement was last executed). An example shows that generators can be trivially easy to create:

def reverse(data):
	for index in range(len(data)-1, -1, -1):
		yield data[index]
 
for char in reverse('golf'):
	print char # flog

Anything that can be done with generators can also be done with class based iterators as described in the previous section. What makes generators so compact is that the __iter__() and next() methods are created automatically.

Some simple generators can be coded succinctly as expressions using a syntax similar to list comprehensions but with parentheses instead of brackets. These expressions are designed for situations where the generator is used right away by an enclosing function.

# Kvadratu suma
print sum(i*i for i in range(10)) # 285
 
data = 'golf'
print list(data[i] for i in range(len(data)-1,-1,-1)) # ['f', 'l', 'o', 'g']