设为首页 收藏本站
查看: 574|回复: 0

[经验分享] Python Tutorial 学习(九)

[复制链接]

尚未签到

发表于 2015-12-1 09:01:56 | 显示全部楼层 |阅读模式
## 9.>

  Compared with other programming languages, Python’s>


  In C++ terminology, normally>


  (Lacking universally accepted terminology to talk about>

## 9.1. A Word About Names and Objects

  Objects have individuality, and multiple names (in multiple scopes) can be bound to the same object. This is known as aliasing in other languages. This is usually not appreciated on a first glance at Python, and can be safely ignored when dealing with immutable basic types (numbers, strings, tuples). However, aliasing has a possibly surprising effect on the semantics of Python code involving mutable objects such as lists, dictionaries, and most other types. This is usually used to the benefit of the program, since aliases behave like pointers in some respects. For example, passing an object is cheap since only a pointer is passed by the implementation; and if a function modifies an object passed as an argument, the caller will see the change — this eliminates the need for two different argument passing mechanisms as in Pascal.


## 9.2. Python Scopes and Namespaces

  A namespace is a mapping from names to objects.
  Most namespaces are currently implemented as Python dictionaries, but that’s normally not noticeable in any way (except for performance), and it may change in the future.
  Examples of namespaces are: the set of built-in names (containing functions such as abs(), and built-in exception names); the global names in a module; and the local names in a function invocation.
  In a sense the set of attributes of an object also form a namespace.

  The important thing to know about namespaces is that there is absolutely no>  for instance, two different modules may both define a function maximize without confusion — users of the modules must prefix it with the module name.


  9.3. A First Look at>  Classes introduce a little bit of new syntax, three new object types, and some new semantics.

  9.3.1.>
  The simplest form of>
  class>  
  .
  .
  .
  Class definitions, like function definitions (def statements) must be executed before they have any effect. (You could conceivably place a>

  In practice, the statements inside a>
  When a>
  When a>
  9.3.2.>  Class objects support two kinds of operations: attribute references and instantiation.

  Attribute references use the standard syntax used for all attribute references in Python: obj.name. Valid attribute names are all the names that were in the>  class MyClass:

  """A simple example>  i = 12345
  def f(self):
  return 'hello world'

  then MyClass.i and MyClass.f are valid attribute references, returning an integer and a function object, respectively.>doc is also a valid attribute, returning the docstring belonging to the>
  Class instantiation uses function notation. Just pretend that the>  x = MyClass()

  creates a new instance of the>  The instantiation operation (“calling” a>init(), like this:
  def init(self):
  self.data = []

  When a>init() method,>init() for the newly-created>  x = MyClass()
  Of course, the init() method may have arguments for greater flexibility. In that case, arguments given to the>init(). For example,



  class Complex:
  ... def init(self, realpart, imagpart):
  ... self.r = realpart
  ... self.i = imagpart
  ...
  x = Complex(3.0, -4.5)
  x.r, x.i
  (3.0, -4.5)
  9.3.3. Instance Objects
  Now what can we do with instance objects? The only operations understood by instance objects are attribute references. There are two kinds of valid attribute names, data attributes and methods.



  data attributes correspond to “instance variables” in Smalltalk, and to “data members” in C++. Data attributes need not be declared; like local variables, they spring into existence when they are first assigned to. For example, if x is the instance of MyClass created above, the following piece of code will print the value 16, without leaving a trace:
  x.counter = 1
  while x.counter < 10:
  x.counter = x.counter * 2
  print x.counter
  del x.counter

  The other kind of instance attribute reference is a method. A method is a function that “belongs to” an object. (In Python, the term method is not unique to>
  Valid method names of an instance object depend on its>  9.3.4. Method Objects
  Usually, a method is called right after it is bound:
  x.f()
  In the MyClass example, this will return the string 'hello world'. However, it is not necessary to call a method right away: x.f is a method object, and can be stored away and called at a later time. For example:
  xf = x.f
  while True:
  print xf()
  will continue to print hello world until the end of time.
  What exactly happens when a method is called? You may have noticed that x.f() was called without an argument above, even though the function definition for f() specified an argument. What happened to the argument? Surely Python raises an exception when a function that requires an argument is called without any — even if the argument isn’t actually used...
  Actually, you may have guessed the answer: the special thing about methods is that the object is passed as the first argument of the function. In our example, the call x.f() is exactly equivalent to MyClass.f(x). In general, calling a method with a list of n arguments is equivalent to calling the corresponding function with an argument list that is created by inserting the method’s object before the first argument.

  If you still don’t understand how methods work, a look at the implementation can perhaps clarify matters. When an instance attribute is referenced that isn’t a data attribute, its>
  9.3.5.>  Generally speaking, instance variables are for data unique to each instance and>  class Dog:
  

kind = 'canine'         #>

  
def __init__(self, name):
  self.name = name    # instance variable unique to each instance
  



  d = Dog('Fido')
  e = Dog('Buddy')
  d.kind # shared by all dogs
  'canine'
  e.kind # shared by all dogs
  'canine'
  d.name # unique to d
  'Fido'
  e.name # unique to e
  'Buddy'As discussed in A Word About Names and Objects, shared data can have possibly surprising effects with involving mutable objects such as lists and dictionaries. For example, the tricks list in the following code should not be used as a>


  class Dog:
  

tricks = []             # mistaken use of a>

  
def __init__(self, name):
  self.name = name
  

  
def add_trick(self, trick):
  self.tricks.append(trick)
  



  d = Dog('Fido')
  e = Dog('Buddy')
  d.add_trick('roll over')
  e.add_trick('play dead')
  d.tricks # unexpectedly shared by all dogs

  ['roll over', 'play dead']Correct design of the>


  class Dog:
  

def __init__(self, name):  self.name = name
  self.tricks = []    # creates a new empty list for each dog
  

  
def add_trick(self, trick):
  self.tricks.append(trick)
  



  d = Dog('Fido')
  e = Dog('Buddy')
  d.add_trick('roll over')
  e.add_trick('play dead')
  d.tricks
  ['roll over']
  e.tricks
  ['play dead']9.4. Random Remarks
  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. Possible conventions include capitalizing method names, prefixing data attribute names with a small unique string (perhaps just an underscore), or using verbs for methods and nouns for data attributes.




  Data attributes may be referenced by methods as well as by ordinary users (“clients”) of an object. In other words,>  Clients should use data attributes with care — clients may mess up invariants maintained by the methods by stamping on their data attributes. Note that clients may add data attributes of their own to an instance object without affecting the validity of the methods, as long as name conflicts are avoided — again, a naming convention can save a lot of headaches here.
  There is no shorthand for referencing data attributes (or other methods!) from within methods. I find that this actually increases the readability of methods: there is no chance of confusing local variables and instance variables when glancing through a method.

  Often, the first argument of a method is called self. This is nothing more than a convention: the name self has absolutely no special meaning to Python. Note, however, that by not following the convention your code may be less readable to other Python programmers, and it is also conceivable that a>
  Any function object that is a>
Function defined outside the>  def f1(self, x, y):
  return min(x, x+y)
  class C:
  f = f1
  def g(self):
  return 'hello world'
  h = g

  Now f, g and h are all attributes of>  Methods may call other methods by using method attributes of the self argument:
  class Bag:
  def init(self):
  self.data = []
  def add(self, x):
  self.data.append(x)
  def addtwice(self, x):
  self.add(x)
  self.add(x)

  Methods may reference global names in the same way as ordinary functions. The global scope associated with a method is the module containing its definition. (A>  Each value is an object, and therefore has a>class.
  9.5. Inheritance

  Of course, a language feature would not be worthy of the name “class” without supporting inheritance. The syntax for a derived>  class DerivedClassName(BaseClassName):
  
  .
  .
  .
  The name BaseClassName must be defined in a scope containing the derived>

  class DerivedClassName(modname.BaseClassName):Execution of a derived>
  There’s nothing special about instantiation of derived>
  Derived>
  An overriding method in a derived>  Python has two built-in functions that work with inheritance:

  Use isinstance() to check an instance’s type: isinstance(obj, int) will be True only if obj.class is int or some>
  Use issubclass() to check>  9.5.1. Multiple Inheritance

  Python supports a limited form of multiple inheritance as well. A>  class DerivedClassName(Base1, Base2, Base3):
  
  .
  .
  .
  For old-style>

  (To some people breadth first — searching Base2 and Base3 before the base>
  For new-style>
  With new-style>
  9.6. Private Variables and>  “Private” instance variables that cannot be accessed except from inside an object don’t exist in Python. However, there is a convention that is followed by most Python code: a name prefixed with an underscore (e.g. _spam) should be treated as a non-public part of the API (whether it is a function, a method or a data member). It should be considered an implementation detail and subject to change without notice.

  Since there is a valid use-case for>  Name mangling is helpful for letting subclasses override methods without breaking intraclass method calls. For example:
  class Mapping:
  def init(self, iterable):
  self.items_list = []
  self.__update(iterable)
  

def update(self, iterable):  for item in iterable:
  self.items_list.append(item)
  

  
__update = update   # private copy of original update() method
  

  class MappingSubclass(Mapping):
  

def update(self, keys, values):  # provides new signature for update()
  # but does not break __init__()
  for item in zip(keys, values):
  self.items_list.append(item)
  

  Note that the mangling rules are designed mostly to avoid accidents; it still is possible to access or modify a variable that is considered private. This can even be useful in special circumstances, such as in the debugger.
  Notice that code passed to exec, eval() or execfile() does not consider the>dict directly.
  9.7. Odds and Ends

  Sometimes it is useful to have a data type similar to the Pascal “record” or C “struct”, bundling together a few named data items. An empty>  class Employee:
  pass
  john = Employee() # Create an empty employee record

Fill the fields of the record
  john.name = 'John Doe'
  john.dept = 'computer lab'
  john.salary = 1000

  A piece of Python code that expects a particular abstract data type can often be passed a>  Instance method objects have attributes, too: m.im_self is the instance object with the method m(), and m.im_func is the function object corresponding to the method.

  9.8. Exceptions Are>
  User-defined exceptions are>  There are two new valid (semantic) forms for the raise statement:

  raise>  raise instance

  In the first form, instance must be an instance of>  raise instance.class, instance

  A>  class B:
  pass
  class C(B):
  pass
  class D(C):
  pass
  for c in [B, C, D]:
  try:
  raise c()
  except D:
  print "D"
  except C:
  print "C"
  except B:
  print "B"
  Note that if the except clauses were reversed (with except B first), it would have printed B, B, B — the first matching except clause is triggered.

  When an error message is printed for an unhandled exception, the exception’s>  9.9. Iterators
  By now you have probably noticed that most container objects can be looped over using a for statement:
  for element in [1, 2, 3]:
  print element
  for element in (1, 2, 3):
  print element
  for key in {'one':1, 'two':2}:
  print key
  for char in "123":
  print char
  for line in open("myfile.txt"):
  print line,
  This style of access is clear, concise, and convenient. The use of iterators pervades and unifies Python. Behind the scenes, the for statement calls iter() on the container object. The function returns an iterator object that defines the method next() which accesses elements in the container one at a time. When there are no more elements, next() raises a StopIteration exception which tells the for loop to terminate. This example shows how it all works:



  s = 'abc'
  it = iter(s)
  it
  
  it.next()
  'a'
  it.next()
  'b'
  it.next()
  'c'
  it.next()
  Traceback (most recent call last):
  File "", line 1, in ?
  it.next()
  StopIteration
  Having seen the mechanics behind the iterator protocol, it is easy to add iterator behavior to your>iter() method which returns an object with a next() method. If the>iter() can just return self:



  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]



  rev = Reverse('spam')
  iter(rev)
  
  for char in rev:
  ... print char
  ...
  m
  a
  p
  s
  9.10. Generators
  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
  ...
  f
  l
  o
  g
  Anything that can be done with generators can also be done with>iter() and next() methods are created automatically.



  Another key feature is that the local variables and execution state are automatically saved between calls. This made the function easier to write and much more clear than an approach using instance variables like self.index and self.data.
  In addition to automatic method creation and saving program state, when generators terminate, they automatically raise StopIteration. In combination, these features make it easy to create iterators with no more effort than writing a regular function.
  9.11. Generator Expressions
  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. Generator expressions are more compact but less versatile than full generator definitions and tend to be more memory friendly than equivalent list comprehensions.
  Examples:



  sum(i*i for i in range(10)) # sum of squares
  285






  xvec = [10, 20, 30]
  yvec = [7, 5, 3]
  sum(x*y for x,y in zip(xvec, yvec)) # dot product
  260






  from math import pi, sin
  sine_table = dict((x, sin(x*pi/180)) for x in range(0, 91))






  unique_words = set(word for line in page for word in line.split())






  valedictorian = max((student.gpa, student.name) for student in graduates)






  data = 'golf'
  list(data for i in range(len(data)-1,-1,-1))
  ['f', 'l', 'o', 'g']
  Footnotes



  [1] Except for one thing. Module objects have a secret read-only attribute called dict which returns the dictionary used to implement the module’s namespace; the name dict is an attribute but not a global name. Obviously, using this violates the abstraction of namespace implementation, and should be restricted to things like post-mortem debuggers.

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-145674-1-1.html 上篇帖子: 让你的Python代码更加pythonic 下篇帖子: Python 类 setattr、getattr、hasattr 的使用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表