文章目录
- 1 作用域
-
- 2 类成员权限
- 3 是否继承新式类
- 4 多重继承
- 5 虚拟子类
- 6 内省【在运行时确定对象类型的能力】
- 7 函数参数
- 8 生成器
1 作用域
1.1 局部作用域
- 1,当局部变量遮盖全局变量,使用
globals()['变量名']
来使用全局变量; - 2,使用
global
重新声明全局变量; - 3,使用
nonlocal
让能够给外部作用域(非全局作用域)内的变量赋值 - 4,如果函数内部需要对行参赋值,以此来影响函数外部的变量,则只能修改参数对象本身;如果参数是不可变,应从函数返回所需要的值【
def func(x):return x + 1
】;
测试程序:
val1 = 2
val2 = 'a'
def testActionScope():
val1 = 3
print(globals()['val1'])
global val2
val2 = 'b'
def nestFunc1():
temp_val = 1
def nestFunc2():
nonlocal temp_val
temp_val = 200
nestFunc2()
return temp_val
if __name__ == '__main__':
testActionScope()
print(val2)
print(nestFunc1())
2 类成员权限
Python中的成员函数和成员变量都是公开的(public),在python中没有类public,private等关键词来修饰成员函数和成员变量。其实,Python并没有真正的私有化支持,但可用下划线得到伪私有。 尽量避免定义以下划线开头的变量!
(1)_xxx "单下划线 " 开始的成员变量叫做保护变量,意思是只有类实例和子类实例能访问到这些变量,需通过类提供的接口进行访问;不能用’from module import *'导入
(2)__xxx 类中的私有变量/方法名 (Python的函数也是对象,所以成员方法称为成员变量也行得通。)," 双下划线 " 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。
(3)xxx 系统定义名字,前后均有一个“双下划线” 代表python里特殊方法专用的标识,如 init()代表类的构造函数。
特殊方式访问私有函数:
class TestClass():
def __testFunc1(self):
print('__testFunc1')
if __name__ == '__main__':
testClass = TestClass()
testClass._TestClass__testFunc1()
3 是否继承新式类
Python 2.x默认类为经典类,而对属性支持完全者为新式类。
- 在python2.x中,从object继承得来的类称为新式类(如class A(object))不从object继承得来的类称为经典类(如class A())
- 新式类跟经典类的差别主要是以下几点:
- 1, 新式类对象可以直接通过__class__属性获取自身类型:type
- 2,继承搜索的顺序发生了改变,经典类多继承时属性搜索顺序: 先深入继承树左侧,再返回,开始找右侧(即深度优先搜索);新式类多继承属性搜索顺序: 先水平搜索,然后再向上移动
如果需要创建新式类,则需要使用__metaclass__ = type
【紧跟在class语句后
面并缩进】
Python 3.x默认即为新式类,不必显式继承于object类。
@property可以把一个实例方法变成其同名属性,以支持.号访问,它亦可标记设置限制,加以规范,
它以一个函数形式,定义一个属性,与@property实现原理类似,或者就是它的的变异用法。
其原型为:
property(fget=None, fset=None, fdel=None, doc=None)
4 多重继承
如果多个超类以不同的方式实现了同一个方法(即有多个同名方法),必须在class语句中小心排列这些超类,因为位于前面的类的方法将覆盖位于后面的类的方法。【方法解析顺序(MRO)】
class Base:
def func(self):
print('Base')
class Derive(Base):
def func(self):
print('Derive')
class Derive2(Base):
def func(self):
print('Derive2')
class A(Derive, Derive2):
pass
if __name__ == '__main__':
5 虚拟子类
虚拟子类:将其他的不是从抽象基类派生的类”注册“到抽象基类,让Python解释器将该类作为抽象基类的子类使用。
这样第三方类不需要直接继承自抽象基类。注册的虚拟子类不论是否实现抽象基类中的抽象内容,Python都认为它是抽象基类的子类,调用 issubclass(子类,抽象基类),isinstance (子类对象,抽象基类)都会返回True。
作用:当一个类继承自抽象基类时,该类必须完成抽象基类定义的语义;当一个类注册为虚拟子类时,这种限制则不再有约束力,可以由程序开发人员自己约束自己,因此提供了更好的灵活性与扩展性。
确定需要哪些类以及这些类应包含哪些方法时,尝试像下面这样做。
(1) 将有关问题的描述(程序需要做什么)记录下来,并给所有的名词、动词和形容词加
上标记。
(2) 在名词中找出可能的类。
(3) 在动词中找出可能的方法。
(4) 在形容词中找出可能的属性。
(5) 将找出的方法和属性分配给各个类。
6 内省【在运行时确定对象类型的能力】
如果要确定对象是由什么组成的,应研究模块inspect。这个模块主要供高级用户创建对象浏览器(让用户能够以图形方式浏览Python对象的程序)以及其他需要这种功能的类似程序。
class Base:
def func(self):
print('Base')
class Derive(Base):
def func(self):
print('Derive')
class Derive2(Base):
def func(self):
print('Derive2')
class A(Derive, Derive2):
pass
if __name__ == '__main__':
a = A()
print(hasattr(a, 'func2'))
print(getattr(a, 'func2', None))
setattr(a, 'func2', 22)
print(a.func2)
def testKwds2(**kwargs):
print(kwargs['gretting'] + kwargs['name'])
if __name__ == '__main__':
import inspect
aa = inspect.signature(testKwds2)
print("inspect.signature(fn)是{0}".format(aa))
print("inspect.signature(fn)的类型是{0}".format(type(aa)))
bb = aa.parameters
print("signature.parameters属性是{0}".format(bb))
print("signature.parameters属性的类型是{0}".format(type(bb)))
for cc, dd in bb.items():
print("mappingproxy.items()返回的值分别是{0},{1}".format(cc, dd))
print("mappingproxy.items()返回的值类型分别是{0},{1}".format(type(cc), type(dd)))
ee = dd.kind
print("parameter.kind属性是{0}".format(ee))
print("parameter.kind属性类型是{0}".format(type(ee)))
gg = dd.default
print("parameter.default属性是{0}".format(gg))
print("parameter.default属性类型是{0}".format(type(gg)))
ff = inspect.Parameter.KEYWORD_ONLY
print("inspect.Parameter.KEYWORD_ONLY属性是{0}".format(ff))
print("inspect.Parameter.KEYWORD_ONLY属性类型是{0}".format(type(ff)))
7 函数参数
def testArgs(x, y, z):
print(x + y + z)
def testKwds(greeting='Hello', name='word'):
print(f'{greeting},{name}')
def testArgs2(*args):
sum = 0
for arg in args:
for a in arg:
sum += a
print(sum)
def testKwds2(**kwargs):
print(kwargs['gretting'] + kwargs['name'])
if __name__ == '__main__':
param = (1, 2, 3)
testArgs(*param)
params = {'name': 'Sir Robin', 'greeting': 'Well met'}
testKwds(**params)
param = (1, 2, 3)
testArgs2(param)
params = {'name': 'Sir Robin', 'greeting': 'Well met'}
testKwds2(name='Sir Robin', gretting='Well met')
8 生成器
def getElemList():
for i in range(1, 10):
yield i
if __name__ == '__main__':
print(list(getElemList()))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)