In Python, everything is an object. Objects are first-class and can be stored in variable and passed to functions.
x = [1, 2, 3, 'a', 'b', 'c']
x
[1, 2, 3, 'a', 'b', 'c']
y = x
y
[1, 2, 3, 'a', 'b', 'c']
x.append("this")
x
[1, 2, 3, 'a', 'b', 'c', 'this']
x.append
<function append>
a_func = x.append
a_func
<function append>
a_func("that")
x
[1, 2, 3, 'a', 'b', 'c', 'this', 'that']
type(x)
list
a_class = type(x)
a_class
list
z = a_class()
type(z)
list
Python's built-in types are good enough in many situations and work together in predictable ways.
my_int = 42
my_float = 42.0
my_str = "42"
my_bool = True
my_int == my_float
True
str(my_int) == my_str
True
bool(my_int) == my_bool
True
[my_int, my_float, my_str, my_bool]
[42, 42.0, '42', True]
{'numbers': (my_int, my_float), 'others': (my_str, my_bool)}
{'numbers': (42, 42.0), 'others': ('42', True)}
Python data types are checked at run-time and not bound to a variable. Functions do not necessarily care about the types of objects passed to them.
my_list = [1, 4.2, True, "Hello, world!"]
len(my_list)
4
my_str = my_list[-1]
my_str
'Hello, world!'
len(my_str)
13
a = my_str.split(',')[0] + '!'
a
'Hello!'
a = my_list[1:3]
a
[4.2, True]
Pretty basic math, but many languages lack this.
x = 42
40 < x < 99
True
1 <= x < 40
False
Integers can take whatever form you need them in.
65 == 0x41 == 0b01000001 == ord('A')
True
The built-in container types can be dynamically constructed.
[x for x in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[x * 1.5 for x in range(10)]
[0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.5, 12.0, 13.5]
[x * 1.5 for x in range(10) if x > 4]
[7.5, 9.0, 10.5, 12.0, 13.5]
{x: x * 1.5 for x in range(10)}
{0: 0.0, 1: 1.5, 2: 3.0, 3: 4.5, 4: 6.0, 5: 7.5, 6: 9.0, 7: 10.5, 8: 12.0, 9: 13.5}
Python contains a mini-language for string formatting (in addition to C-style string formatting).
"vehicle '{0}' has wheel count: {1}".format('car', 4)
"vehicle 'car' has wheel count: 4"
"a score of {:.2%}".format(.96578)
'a score of 96.58%'
"{:,}".format(1000000)
'1,000,000'
"{:.2e}".format(1000000)
'1.00e+06'
Functions arguments can be applied by position or name.
def total(sub, tip, tax=0.06):
return sub + (sub * tax) + tip
total(10.0, 2.0)
12.6
total(10.0, 2.0, 0.10)
13.0
total(10.0, 2.0, tax=0.05)
12.5
total(10.0, tax=0.09, tip=1.5)
12.4
Python's "magic" methods make defining custom classes work well with duck typing.
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "{n} is {a}".format(n=self.name, a=self.age)
def __iadd__(self, years):
self.age += years
return self
def __cmp__(self, other):
return cmp(self.age, other.age)
person = Person("John Smith", 42)
print person
John Smith is 42
person += 1
print person
John Smith is 43
person > Person("Jane Doe", 42)
True
In Python, namespaces are explicit. To refernce an object, it must be in your local or global namespace (or built-in).
class Foo(object):
BAR = 1
def __init__(self, value):
self.value = value # creation of self.value
def __str__(self):
text = ""
text += str(self.value) # instance variable
text += ', '
text += str(self.BAR) # class variable
return text
print Foo(2)
2, 1
The decorator syntax allow dynamic modification of attributes.
def show_call(func):
print "called {0}".format(func.__name__)
return func
class Foo(object):
BAR = 1
@show_call
def __init__(self, value):
self.value = value # creation of self.value
@show_call
def __str__(self):
text = ""
text += str(self.value) # instance variable
text += ', '
text += str(self.BAR) # class variable
return text
print Foo(2)
called __init__ called __str__ 2, 1
Python's standard library contains many useful modules.
from collections import Counter
for char, count in Counter("The quick brown fox jumped over the lazy dog.").items():
if count > 1 and char != ' ':
print char, count
e 4 d 2 h 2 o 4 r 2 u 2
from itertools import permutations
for permutation in permutations(('a', 'b', 'c')):
print permutation
('a', 'b', 'c') ('a', 'c', 'b') ('b', 'a', 'c') ('b', 'c', 'a') ('c', 'a', 'b') ('c', 'b', 'a')
And many more:
The above concepts and many more allow the creation of useful and friendly 3rd-party libraries.
Primary Hosting
Most packages can be installed with pip
:
pip install ProjectName
>>> import requests
>>> requests.get('https://api.github.com/user', auth=('user', 'pass'))
>>> r.status_code
200
>>> r.headers['content-type']
'application/json; charset=utf8'
>>> r.encoding
'utf-8'
>>> r.text
u'{"type":"User"...'
>>> r.json()
{u'private_gists': 419, u'total_private_repos': 77}
File "<ipython-input-81-04b2ed99ac4a>", line 17 {u'private_gists': 419, u'total_private_repos': 77, ...} ^ SyntaxError: invalid syntax
>>> from suds.client import Client
>>> url = 'http://localhost:7080/webservices/WebServiceTestBean?wsdl'
>>> client = Client(url)
>>> print client
Service (WebServiceTestBeanService) tns="http://test.server.enterprise.rhq.org/"
Prefixes (1):
ns0 = "http://test.server.enterprise.rhq.org/"
Ports (1):
(Soap)
Methods:
addPerson(Person person, )
echo(xs:string arg0, )
getList(xs:string str, xs:int length, )
getPercentBodyFat(xs:string name, xs:int height, xs:int weight)
getPersonByName(Name name, )
hello()
testExceptions()
testListArg(xs:string[] list, )
testVoid()
updatePerson(AnotherPerson person, name name, )
Types (23):
Person
Name
Phone
AnotherPerson
>>> from sh import git, ls, wc
>>> git(checkout="master")
>>> print ls("-l")
>>> longest_line = wc(__file__, "-L")
>>> import serial
>>> ser = serial.Serial('COM1')
>>> ser.write("hello")
>>> ser.close()
>>> from veracity import Repository, WorkingCopy, Item
>>> repo = Repository('veracity', remote='http://public.veracity-scm.com/repos/veracity')
>>> print repo.name
>>> print repo.users
>>> print repo.branches
>>> print repo.tags
>>> work = repo.checkout("~/v/veracity")
>>> work.delete()
>>> work = WorkingCopy("~/v/veracity", repo='veracity')
>>> work.update(branch='master')
>>> item = Item('docs/GettingStarted.txt', work=work)
>>> item.lock()