python学习笔记

The first is used to initialise newly created object, and receives arguments used to do that:

class foo:
    def __init__(self, a, b, c):
        # ...

x = foo(1, 2, 3) # __init__

The second implements function call operator.

class foo:
    def __call__(self, a, b, c):
        # ...

x = foo()
x(1, 2, 3) # __call__



it's a list of public objects of that module -- it overrides the default of hiding everything that begins with an underscore

Linked to, but not explicitly mentioned here, is exactly when __all__ is used. It is a list of strings defining what symbols in a module will be exported when from <module> import * is used on the module.

For example, the following code in a foo.py explicitly exports the symbols bar and baz:

__all__ = ['bar', 'baz']

waz = 5
bar = 10
def baz(): return 'baz'

These symbols can then be imported like so:

from foo import *

print bar
print baz

# The following will trigger an exception, as "waz" is not exported by the module
print waz

If the __all__ above is commented out, this code will then execute to completion, as the default behaviour of import * is to import all symbols that do not begin with an underscore, from the given namespace.

It's important to note that __all__ only affects the behavior of from <module> import *. Members that are not mentioned in __all__ as still accessible from outside the module and can be imported with from <module> import <member>

By "shallow copying" it means the content of the dictionary is not copied by value, but just creating a new reference.

>>> a = {1: [1,2,3]}
>>> b = a.copy()
>>> a, b
({1: [1, 2, 3]}, {1: [1, 2, 3]})
>>> a[1].append(4)
>>> a, b
({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})

In contrast, a deep copy will copy all contents by value.

>>> c = copy.deepcopy(a)
>>> a, c
({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})
>>> a[1].append(5)
>>> a, c
({1: [1, 2, 3, 4, 5]}, {1: [1, 2, 3, 4]})

So:

  1. a = b: Reference assignment, Make a and b points to the same object.

    a ---,
         v
         {1: L}
         ^   |
    b ---'   '----> [1,2,3]
  2. a = b.copy(): Shallow copying, a and b will become two isolated objects, but their contents still share the same reference

    a ---> {1: L}
               |             
               >---> [1,2,3]
               |
    b ---> {1: M}
  3. a = copy.deepcopy(b): Deep copying, a and b's structure and content become completely isolated.

    a ---> {1: L}
               ‘-----> [1,2,3]
    b ---> {1: M}
               ‘-----> [1,2,3]
Ref:   http://stackoverflow.com/questions/3975376/understanding-dict-copy-shallow-or-deep

  • Fun With Python Function Parameters


Virtually every programming language has functions and procedures, a way of separating out a block of code that can be called many times from different places in your program, and a way to pass parameters into them. Python is no different, so we'll quickly run over the standard stuff that most languages have, then take a look at some of the cool stuff Python has to offer.

Ref:   http://www.pythoncentral.io/fun-with-python-function-parameters/

In Python versions prior to 3.0 there are two kinds of strings "plain strings" and "unicode strings". Plain strings (str) cannot represent characters outside of the Latin alphabet (ignoring details of code pages for simplicity). Unicode strings (unicode) can represent characters from any alphabet including some fictional ones like Klingon.

So why have two kinds of strings, would it not be better to just have Unicode since that would cover all the cases? Well it is better to have only Unicode but Python was created before Unicode was the preferred method for representing strings. It takes time to transition the string type in a language with many users, in Python 3.0 it is finally the case that all strings are Unicode.

The inheritance hierarchy of Python strings pre-3.0 is:

          object
             |
             |
         basestring
            / \
           /   \
         str  unicode

'basestring' introduced in Python 2.3 can be thought of as a step in the direction of string unification as it can be used to check whether an object is an instance of str or unicode

>>> string1 = "I am a plain string"
>>> string2 = u"I am a unicode string"
>>> isinstance(string1, str)
True
>>> isinstance(string2, str)
False
>>> isinstance(string1, unicode)
False
>>> isinstance(string2, unicode)
True
>>> isinstance(string1, basestring)
True
>>> isinstance(string2, basestring)
True
Ref:  http://stackoverflow.com/questions/1979004/what-is-the-difference-between-isinstanceaaa-basestring-and-isinstanceaaa

If it's in a class, you can use getattr:

class MyClass(object):
    def install(self):
          print "In install"

method_name = 'install' # set by the command line options
my_cls = MyClass()
method = getattr(my_cls, method_name)
if not method:
    raise Exception("Method %s not implemented" % method_name)
method()

or if it's a function:

def install():
       print "In install"

method_name = 'install' # set by the command line options
possibles = globals().copy()
possibles.update(locals())
method = possibles.get(method_name)()  # equal to: possibles[method_name]()  
if not method:
     raise Exception("Method %s not implemented" % method_name)
method()
Ref:  http://stackoverflow.com/questions/7936572/python-call-a-function-from-string-name

The Python standard library defines an any() function that

Return True if any element of the iterable is true. If the iterable is empty, return False.

How about:

>>> any(isinstance(e, int) and e > 0 for e in [1,2,'joe'])
True

It also works with all() of course:

>>> all(isinstance(e, int) and e > 0 for e in [1,2,'joe'])
False
Ref:   http://stackoverflow.com/questions/2012611/any-function-in-python-with-a-callback

How about:

>>> 'hello world'[::-1]
'dlrow olleh'

This is extended slice syntax. It works by doing [begin:end:step] - by leaving begin and end off and specifying a step of -1, it reverses a string.

Ref:  http://stackoverflow.com/questions/931092/reverse-a-string-in-python

It is not possible to sort a dict, only to get a representation of a dict that is sorted. Dicts are inherently orderless, but other types, such as lists and tuples, are not. So you need a sorted representation, which will be a list—probably a list of tuples.

For instance,

import operator
x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
sorted_x = sorted(x.iteritems(), key=operator.itemgetter(1))

sorted_x will be a list of tuples sorted by the second element in each tuple. dict(sorted_x) == x.

Update:  I used a lambda:  sorted(d.items(), key=lambda x: x[1])


z = dict(x.items() + y.items())

This will, as you want it, put the final dict in z, and make the value for b be properly overridden by the second (y) dict's value:

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = dict(x.items() + y.items())
>>> z
{'a': 1, 'c': 11, 'b': 10}

Upate:   analogous, less memory consuming: dict(chain(x.iteritems(), y.iteritems())) (from itertools import chain), and in py3k dict(chain(x.items(), y.items()))


To understand what  yield  does, you must understand what generators are. And before generators come iterables.



Arguments are passed by assignment. The reason people are confused by the behaviour is twofold:

  1. the parameter passed in is actually a reference to an object (but the reference is passed by value)
  2. some data types are mutable, but others aren't

So:

  • If you pass a mutable object into a method, the method gets a reference to that same object and you can mutate it to your heart's delight, but if you rebind the reference in the method, the outer scope will know nothing about it, and after you're done, the outer reference will still point at the original object.

  • If you pass an immutable object to a method, you still can't rebind the outer reference, and you can't even mutate the object.

Okay, this is a little confusing. Let's have some examples.

List - a mutable type

Let's try to modify the list that was passed to a method:

def try_to_change_list_contents(the_list):
    print 'got', the_list
    the_list.append('four')
    print 'changed to', the_list

outer_list = ['one', 'two', 'three']

print 'before, outer_list =', outer_list
try_to_change_list_contents(outer_list)
print 'after, outer_list =', outer_list

Output:

before, outer_list = ['one', 'two', 'three']
got ['one', 'two', 'three']
changed to ['one', 'two', 'three', 'four']
after, outer_list = ['one', 'two', 'three', 'four']

Since the parameter passed in is a reference to outer_list, not a copy of it, we can use the mutating list methods to change it and have the changes reflected in the outer scope.

Now let's see what happens when we try to change the reference that was passed in as a parameter:

def try_to_change_list_reference(the_list):
    print 'got', the_list
    the_list = ['and', 'we', 'can', 'not', 'lie']
    print 'set to', the_list

outer_list = ['we', 'like', 'proper', 'English']

print 'before, outer_list =', outer_list
try_to_change_list_reference(outer_list)
print 'after, outer_list =', outer_list

Output:

before, outer_list = ['we', 'like', 'proper', 'English']
got ['we', 'like', 'proper', 'English']
set to ['and', 'we', 'can', 'not', 'lie']
after, outer_list = ['we', 'like', 'proper', 'English']

Since the the_list parameter was passed by value, assigning a new list to it had no effect that the code outside the method could see. The the_list was a copy of the outer_list reference, and we had the_list point to a new list, but there was no way to change where outer_list pointed.

String - an immutable type

It's immutable, so there's nothing we can do to change the contents of the string

Now, let's try to change the reference

def try_to_change_string_reference(the_string):
    print 'got', the_string
    the_string = 'In a kingdom by the sea'
    print 'set to', the_string

outer_string = 'It was many and many a year ago'

print 'before, outer_string =', outer_string
try_to_change_string_reference(outer_string)
print 'after, outer_string =', outer_string

Output:

before, outer_string = It was many and many a year ago
got It was many and many a year ago
set to In a kingdom by the sea
after, outer_string = It was many and many a year ago

Again, since the the_string parameter was passed by value, assigning a new string to it had no effect that the code outside the method could see. The the_string was a copy of the outer_string reference, and we had the_string point to a new list, but there was no way to change where outer_string pointed.

I hope this clears things up a little.


Best way to check if a list is empty

if not a:
  print "List is empty"

Using the implicit booleanness of the empty list is quite pythonic.



When the Python interpreter reads a source file, it executes all of the code found in it. Before executing the code, it will define a few special variables. For example, if the python interpreter is running that module (the source file) as the main program, it sets the special __name__ variable to have a value "__main__". If this file is being imported from another module, __name__ will be set to the module's name.

In the case of your script, let's assume that it's executing as the main function, e.g. you said something like

python threading_example.py

on the command line. After setting up the special variables, it will execute the import statement and load those modules. It will then evaluate the def block, creating a function object and creating a variable called myfunction that points to the function object. It will then read the if statement and see that __name__ does equal "__main__", so it will execute the block shown there.

One of the reasons for doing this is that sometimes you write a module (a .py file) where it can be executed directly. Alternatively, it can also be imported and used in another module. By doing the main check, you can have that code only execute when you want to run the module as a program and not have it execute when someone just wants to import your module and call your functions themselves.

See this page for some extra details.



append:

x = [1, 2, 3]
x.append([4, 5])
print (x)

gives you: [1, 2, 3, [4, 5]]


extend:

x = [1, 2, 3]
x.extend([4, 5])
print (x)

gives you: [1, 2, 3, 4, 5]



Enclose in parentheses:

except (IDontLIkeYouException, YouAreBeingMeanException) as e:
    pass

Separating the exception from the variable with a comma will still work in Python 2.6 and 2.7, but is now deprecated; now you should be using as.



Variables declared inside the class definition, but not inside a method are class or static variables:

>>> class MyClass:
...     i = 3
...
>>> MyClass.i
3 


>>> x = "Hello World!"
>>> x[2:]
'llo World!'
>>> x[:2]
'He'
>>> x[:-2]
'Hello Worl'
>>> x[-2:]
'd!'
>>> x[2:-2]
'llo Worl'

Python calls this concept "slicing" and it works on more than just strings. Take a look here for a comprehensive introduction.





How to know if an object has an attribute in Python

Try hasattr():

if hasattr(a, 'property'):
    a.property

EDIT: See zweiterlinde's answer below, who offers good advice about asking forgiveness! A very pythonic approach!

The general practice in python is that, if the property is likely to be there most of the time, simply call it and either let the exception propagate, or trap it with a try/except block. This will likely be faster than hasattr. If the property is likely to not be there most of the time, or you're not sure, using hasattrwill probably be faster than repeatedly falling into an exception block.



Calling a function from a string with the function's name in Python

Assuming module foo with method bar:

import foo
methodToCall = getattr(foo, 'bar')
result = methodToCall()

As far as that goes, lines 2 and 3 can be compressed to:

result = getattr(foo, 'bar')()

if that makes more sense for your use case. You can use getattr in this fashion on class instance bound methods, module-level methods, class methods... the list goes on.


Have you tried the __name__ attribute of the class? ie x.__class__.__name__ will give you the name of the class, which I think is what you want.

>>> import itertools
>>> x = itertools.count(0)
>>> x.__class__.__name__
'count'

It should work similarly from wherever you call it.


How do I manually throw/raise an exception in python?

Can't get much more pythonic than this:

raise Exception("I know python!")

See the raise statement docs for python if you'd like more info.

Ref:  http://stackoverflow.com/questions/2052390/how-do-i-manually-throw-raise-an-exception-in-python

When to use %r instead of %s in Python?

he %s specifier converts the object using str(), and %r converts it using repr().

For some objects such as integers, they yield the same result, but repr() is special in that (for types where this is possible) it conventionally returns a result that is valid Python syntax, which could be used to unambiguously recreate the object it represents.

Here's an example, using a date:

>>> d = datetime.date.today()
>>> str(d)
'2011-05-14'
>>> repr(d)
'datetime.date(2011, 5, 14)'

Types for which repr() doesn't produce Python syntax include those that point to external resources such as a file, which you can't guarantee to recreate in a different context.


You can convert a Unicode string to a Python byte string using  uni.encode(encoding) , and you can convert a byte string to a Unicode string using  s.decode(encoding)

That is:

>>> 'abc'.decode('utf-8')  # str to unicode
u'abc'
>>> u'abc'.encode('utf-8') # unicode to str
'abc' 
Ref:  http://stackoverflow.com/questions/10288016/usage-of-unicode-and-encode-functions-in-python
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值