The Python Tutorial之Class(一)

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.
  • 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.

理解nameobject的关系是基础,这里name相当于指针,如果在函数内改变该对象的值,在函数外将会看到这种改变,理解这点需要简单敲些代码:

>>> def change(x,y):
		x=2
		y=y.append('a')

	
>>> x=1
>>> y=[0]
>>> change(x,y)
>>> x
1
>>> y
[0, 'a']
>>>

从结果来看,很明显y作为列表类型的变元,在函数中改变了值;而x引用的是1这个常量无法改变,所以打印结果还是1,但是在change函数中,确实将x赋值2,该x的也确实存在,只不过namespace空间不同而已。

2. Python Scopes and Namespaces

  • A namespace is a mapping from names to objects.
  • 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
  • the local names in a function invocation
  • the set of attributes of an object also form a namespace.
  • The important thing to know about namespaces is that there is absolutely no relation between names in different namespaces; for instance, two different modules may both define a function maximize without confusion — users of the modules must prefix it with the module name.

笔者将引用内容稍微排版,这样就很清楚了。上面的例子中x指向1对象x指向2对象的命名空间不同,前者处于global names,后者处于local names。接下来个概念更加的绕:

  • 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. In this case there happens to be a straightforward mapping between the module’s attributes and the global names defined in the module: they share the same namespace!
    认为moudle的attributes和global names处于同一命名空间,注意回到Examples of namespaces部分再品味下

如果接受第一条的设定,那么第二条也很容易理解,看如下代码:

class function1 ()
    def fun ()print("hello\n")

def function ()
    print("world\n")
# 保存为nametest.py
import nametest.py

之后对其的引用:nametest.function 或者nametest.function1都属于module自身的attribute的引用,而functionfunction1(名字)都处于global namespace

Namespaces are created at different moments and have different lifetimes:

  • The namespace containing the built-in names is created when the Python interpreter starts up, and is never deleted.
  • The global namespace for a module is created when the module definition is read in; normally, module namespaces also last until the interpreter quits.
    • The statements executed by the top-level invocation of the interpreter, either read from a script file or interactively, are considered part of a module called main, so they have their own global namespace.
  • The local namespace for a function is created when the function is called, and deleted when the function returns or raises an exception that is not handled within the function. Of course, recursive invocations each have their own local namespace.

上面的引用解释了几个问题:builtins模块的namespace在解释器启动的时候引入,永不被删除;_main_模块的namespace在解释器执行第一条语句时引入,持续到解释器退出;函数有自己的local namespace,该空间在函数调用时引入,函数返回或者异常抛出时删除。接下来看看scope

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.
第一句话说namespace和scope的关系,不加限定词对一个对象的引用(xxx.xxx.object就是加限定词的意思)按照下面的顺序查找scope:

  • the innermost scope, which is searched first, contains the local names
  • the scopes of any enclosing functions, which are searched starting with the nearest enclosing scope, contains non-local, but also non-global names
  • the next-to-last scope contains the current module’s global names
  • the outermost scope (searched last) is the namespace containing built-in names

然后官网手册列了下面两个列子:

  • If a name is declared global, then all references and assignments go directly to the middle scope containing the module’s global names.
  • To rebind variables found outside of the innermost scope, the nonlocal statement can be used; if not declared nonlocal, those variables are read-only (an attempt to write to such a variable will simply create a new local variable in the innermost scope, leaving the identically named outer variable unchanged).

敲敲代码解释一波:

#第一点
>>> def change(x):
		 global y
		 y=x

	 
>>> y=1
>>> change(10)
>>> y
10
>>> 
#第二点
>>> def change(x):
	    y=2;
	    def change1(z):
	        y=z
	    change1(x)
	    print(y)

>>> change(1)
2
>>> def change(x):
	    y=2;
	    def change1(z):
	        nonlocal y #言简意赅的说就是nonlocal改变了y的namespace
	        y=z
	    change1(x)
	    print(y)

>>> change(1)
1

Usually, the local scope references the local names of the (textually) current function. Outside functions, the local scope references the same namespace as the global scope: the module’s namespace. Class definitions place yet another namespace in the local scope.

先理解上面的引用,local scopelocal namespace或者global namespace,class的定义会开辟另一个namespace在global namespace(又叫local scope)。然后看下面的引用,特别第三点:

It is important to realize that scopes are determined textually:

  • the global scope of a function defined in a module is that module’s namespace, no matter from where or by what alias the function is called. On the other hand, the actual search for names is done dynamically, at run time.
  • A special quirk of Python is that – if no global statement is in effect – assignments to names 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.)这里local scope指global namespaces,括号里面的情况是local namespaces的情况

3. Scopes and Namespaces Example

最后看看官网的例子:

def scope_test():
    def do_local():
        spam = "local spam"

    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"

    def do_global():
        global spam
        spam = "global spam"

    spam = "test spam"
    do_local()
    print("After local assignment:", spam)
    do_nonlocal()
    print("After nonlocal assignment:", spam)
    do_global()
    print("After global assignment:", spam)

scope_test()
print("In global scope:", spam)

结果:

After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam

经过上面的学习一路,很容易解释这种结果,特别最后After global assignment: nonlocal spam,因为此时spam的引用首先查找的是scope_testlocal namespace

4. 总结

在这一篇理解了什么是namespace及namespace的分类,scope和namespace的关系,最后结合了一个例子充分理解上述理论的实际情况。实际上很多python入门书或者课程,都会隔过去这里,只是介绍下nonlocal或者global的用法。理解这里对于后续编写脚本至关重要。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要爬取 https://www.runoob.com/manual/pythontutorial/docs/html/ 中的一段文本,可以使用 Python 的 requests 库和 BeautifulSoup 库。 以下是一个示例代码,用于爬取 Python 教程中第一篇文章的第一段内容: ```python import requests from bs4 import BeautifulSoup url = 'https://www.runoob.com/manual/pythontutorial/docs/html/python-beginner.html' response = requests.get(url) soup = BeautifulSoup(response.text, 'html.parser') content = soup.find('div', class_='article-intro').p.text.strip() print(content) ``` 首先,使用 requests 库获取 Python 教程的第一篇文章的页面内容,并将其存储在变量 response 中。 接着,使用 BeautifulSoup 库解析页面内容,并使用 `soup.find()` 方法找到页面中的 class 为 `article-intro` 的 div 元素,然后再从这个 div 元素中找到第一个 p 标签元素。 最后,使用 `text` 属性获取 p 标签元素的文本内容,并使用 `strip()` 方法去除文本内容前后的空格和换行符。 执行上述代码,输出第一篇文章的第一段内容: ``` Python 是一种解释型、面向对象、动态数据类型的高级程序设计语言。Python 由 Guido van Rossum 于 1989 年底发明,第一个公开发行版发行于 1991 年。Python 语法简洁而清晰,具有丰富和强大的类库。它常被称为胶水语言,能够把用其他语言制作的各种模块(尤其是 C/C++)很轻松地联结在一起。Python 适用于大多数平台,包括 Windows、Linux、Unix、Mac OS X 等,并且有许多第三方库可以帮助我们进行各种操作。 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值