1.python中的几种变量
1)__x 如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__
,在Python中,实例的变量名如果以__
开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name
是因为Python解释器对外把__name
变量改成了_Student__name
,所以,仍然可以通过_Student__name
来访问__name
变量
2) __x__需要注意的是,在Python中,变量名类似__xxx__
的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__
、__score__
这样的变量名。
3) _x有些时候,你会看到以一个下划线开头的实例变量名,比如_name
,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
2.python中几种特殊的函数
__func表示不希望外部访问,但是事实上也可以访问,这体现了python的设计哲学,只提供建议,一切全靠自觉。
__func__是可以被重写的函数,被其他函数隐式调用,这些实际上是用来定制类的方法
__len__ len()其实调用了__len__
__str__被print隐式调用
__repr__ 直接显示变量时候调用,(两者的区别是__str__()
返回用户看到的字符串,而__repr__()
返回程序开发者看到的字符串,也就是说,__repr__()
是为调试服务的)
__iter__ 如果一个类想被用于for ... in
循环,类似list或tuple那样,就必须实现一个__iter__()
方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()
方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。(通常也需要重写next方法)
__getitem__ 要表现得像list那样按照下标取出元素,需要实现__getitem__()
方法
_setitem__()
方法,把对象视作list或dict来对集合赋值。最后,还有一个__delitem__()
方法,用于删除某个元素
__slot__用来限制类可以添加的属性
Python允许在定义class的时候,定义一个特殊的__slots__
变量,来限制该class能添加的属性。使用__slots__
要注意,__slots__
定义的属性仅对当前类起作用,对继承的子类是不起作用的。除非在子类中也定义__slots__
,这样,子类允许定义的属性就是自身的__slots__
加上父类的__slots__
。
__getattr__ 正常情况下,当我们调用类的方法或属性时,如果不存在,就会报错。要避免这个错误,除了可以加原来没有的属性外,Python还有另一个机制,那就是写一个__getattr__()
方法,动态返回一个属性。只有在没有找到属性的情况下,才调用__getattr__
,已有的属性,比如name
,不会在__getattr__
中查找。
__call__ 只需要定义一个__call__()
方法,就可以直接对实例进行调用,__call__()
还可以定义参数。对实例进行直接调用就好比对一个函数进行调用一样,所以你完全可以把对象看成函数,把函数看成对象,因为这两者之间本来就没啥根本的区别。怎么判断一个变量是对象还是函数呢?其实,更多的时候,我们需要判断一个对象是否能被调用,能被调用的对象就是一个Callable
对象,比如函数和我们上面定义的带有__call()__
的类实例
1)type()判断对象类型
2)isinstance()判断对象类型,判断是否继承子某个父类
3)dir() 如果要获得一个对象的所有属性和方法,可以使用dir()
函数,它返回一个包含字符串的list
4) help()获得对象的详细信息
仅仅把属性和方法列出来是不够的,配合getattr()
、setattr()
以及hasattr()
,还可以直接操作一个对象的状态,这些优点类似于其他高级语言中的反射
5)Python内置的@property
装饰器就是负责把一个方法变成属性调用的,多用于getter,与之对应的是@属性.setter