参数的几种用法

位置参数

即将值与形参的位置对应,完成赋值

  1. def say():
  2. print("says %s to %s" % ("hello", "world"))

关键字参数

  1. def say(what, to_who):
  2. print("says {what} to {to_who}".format(what=what, to_who=to_who))
  3. say(to_who='world', what='hello')

收集/分配参数 (可选参数)

* 号 或 ** 号表示的形参,*接收的元组,**接收的是字典

  1. def hello(*para):
  2. # *para : It means any numbers of parameters.Additional, the type of the para is a tuple.
  3. # *para : 表示参数para是不定数量的可选输入的,另外,它的类型是一个元组类型。
  4. print(para) # 注意,这里不是 print(*para)
  5. print(type(para))
  6. def hello_2(**para):
  7. # **para : It means collect the keyword parameters, the type is a dict.
  8. # **para : 表示参数para是搜集关键字参数的,类型为字典。
  9. print(para)
  10. print(type(para))

私有参数

_形参前使用单下划线表示保护类型,只能允许其本身与子类进行访问 __形参前使用双下划线表示私有类型,只能允许这个类本身进行访问了,连子类也不可以用于命名一个类属性(类变量) 不同于 Java,Python 中如果不允许修改生效则需要以“属性”的方式限定

  1. class A:
  2. # 定义类属性(类变量), 可通过类名访问,其被所有实例共享
  3. word = 'hello'
  4. # 以单下划线开头的表示的是protected类型的变量。即保护类型只能允许其本身与子类进行访问。
  5. # 若内部变量标示,如: 当使用“from M import”时,不会将以一个下划线开头的对象引入。
  6. _p1 = 'Mr'
  7. # 双下划线的表示的是私有类型的变量。只能允许这个类本身进行访问了,连子类也不可以用于命名一个类属性(类变量)。
  8. # 调用时名字被改变(在类FooBar内部,__boo变成_FooBar__boo,如self._FooBar__boo)
  9. __p2 = 'Miss'
  10. def p(self):
  11. # 定义实例属性
  12. print(self.word)
  13. print(self._p1)
  14. print(self.__p2)
  15. def i(self):
  16. print(self.word)
  17. print(A._p1)
  18. print(A.__p2)
  19. class B(A, Exception):
  20. pass
  21. if __name__ == '__main__':
  22. a = A()
  23. a._p1 = '1'
  24. a.__p2 = '2'
  25. a.p()
  26. a.word = 'hi'
  27. a.i()
  28. a.__p2 = "what"
  29. b = B()
  30. print(b._p1 + "子类访问._p1")
  31. print(b.__p2 + "子类访问.__p2")

作用域/命名空间

具体文档 https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces

  • 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

也就是说 作用域/命名空间 的定义与查找优先级遵循的是 “L-E-G-B”

  • 作用域根据 Python 语法和缩进而明确
  • 当全局变量与局部(本地)变量重名时,很容易因忽视而出现“遮盖”问题。如果需要使用全局变量,则用 global 声明
  • 如果使用的是函数,即使未声明使用全局变量,也可能会“就近”引用声明 ```python def hi(a): print(a, b)

if name == ‘main‘: b = ‘world’ hi(‘hello’) # 输出结果: hello world

如果意图是使用全局参数,改进的方式:

def hi(a): print(a, globals()[‘b’])

  1. - 嵌套函数中,内部函数的变量意图引用外部函数的变量,可以使用 `nonlocal`
  2. ```python
  3. def say():
  4. b = 'worlds'
  5. def hi():
  6. a = 'hello'
  7. nonlocal b
  8. print(a, b)
  9. hi()
  10. if __name__ == '__main__':
  11. say() # 输出结果: hello worlds