python 特殊变量_python中的特殊变量

类似__xx,以双下划线开头的实例变量名,是一个私有变量(private),只有内部可以访问,外部不能访问;

类似__xx__,以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,它不是private变量,下面会介绍Python中的常见特殊变量;

类似_x,以单下划线开头的实例变量名,这样的变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是请把我视为私有变量,不要随意访问”。

特殊变量

#__name__

如果直接执行某个.py文件的时候,这个文件里面的__name__就是__main__,如果不是直接执行,而是被另外一个.py文件import的时候,这个文件里面的__name__是这个py的文件名。

使用这个__name__可以对程序进行调试,如果说当程序之间互相之间调用,比较复杂的关系的时候,使用if __name__ == '__main__':将执行的代码放在里面,在执行其他的程序的时候,测试的程序本身不会运行,而这个程序有问题的时候,可以执行这个文件,那么if __name__ == '__main__':里面的代码就执行了。

#__doc__

获取模块注释

#__file__

当前执行文件的路径

#__cached__

对应pycache文件的位置

#__name__

执行当前文件的时候,等于__main__;否则不等于;一般在主文件里写

#__package__

模块所在package

#__all__

python模块中的__all__,可用于模块导入时限制,如:

from module import *

此时被导入模块若定义了__all__属性,则只有__all__内指定的属性、方法、类可被导入。

若没定义,则导入模块内的所有公有属性,方法和类 。

# 在别的模块中,导入该模块时,只能导入__all__中的变量,方法和类

__all__ = ('A', 'func')

class A():

def __init__(self, name, age):

self.name = name

self.age = age

class B():

def __init__(self, name, id):

self.name = name

self.id = id

def func():

print('func() is called!')

def func1():

print('func1() is called!')

#test.py中定义了__all__属性,只能导入__all__中定义的属性,方法和类

from test import *

a=A('python','24')

print(a.name,a.age)

func()

#func1() #NameError: name 'func1' is not defined

#b=B('python',123456) #NameError: name 'B' is not defined

#__slots__

Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性范围

class P(object):

__slots__ = ("name", "age")

pass

#__init__()

构造函数,创建实例的时候,可以调用__init__方法做一些初始化的工作,如果子类重写了__init__,实例化子类时,则只会调用子类的__init__,此时如果想使用父类的__init__,可以使用super函数,如下:

class P(object):

def __init__(self, name, score):

self.name = name

self.score = name

class C(P):

def __init__(self, name, score, age):

super(C, self).__init__(name, score)

self.age = age

#__new__()

注意:__init__是实例创建之后调用的第一个方法,而__new__更像构造函数,它在__init__之前被调用。

另外,__new__方法是一个静态方法,第一参数是cls,__new__方法必须返回创建出来的实例。

例如,用__new__实现单例模式:

class Singleton(object):

def __new__(cls):

# 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象

if not hasattr(cls, 'instance'):

cls.instance = super(Singleton, cls).__new__(cls)

return cls.instance

obj1 = Singleton()

obj2 = Singleton()

obj1.attr1 = 'value1'

print(obj1.attr1, obj2.attr1)

print(obj1 is obj2)

#__del__()

析构函数:__del__()    释放对象是自动调用

#__str__()

在调用print打印对象时自动调用,是给用户用的,是一个描述对象的方法。

#__repr__()

是给机器用的,在Python解释器里面直接敲对象名在回车后调用的方法。(用于调试)

# test.py

class P(object):

def __str__(self):

return "__str__ called"

def __repr__(self):

return "__repr__ called"

p = P()

可以看下__str__和__repr__的区别:

>>> from test import p

>>> p

__repr__ called

>>> print p

__str__ called

#__enter__

#__exit__

这两个方法是用于支持with语句的上下文管理器。

例如让文件句柄支持with语法的实现:

class File(object):

def __init__(self, file_name, method):

self.file_obj = open(file_name, method)

def __enter__(self):

return self.file_obj

def __exit__(self, type, value, traceback):

self.file_obj.close()

with File('demo.txt', 'w') as opened_file:

opened_file.write('Hola!')

#__iter__

next

如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。

class Fib(object):

def __init__(self):

self.a, self.b = 0, 1 # 初始化两个计数器a,b

def __iter__(self):

return self # 实例本身就是迭代对象,故返回自己

def next(self):

self.a, self.b = self.b, self.a + self.b # 计算下一个值

if self.a > 100000: # 退出循环的条件

raise StopIteration();

return self.a # 返回下一个值

#__call__

实例可以像函数一样调用。

class Student(object):

def __init__(self):

self.name = "Michael"

def __call__(self):

print('__call__ called')

s = Student()

s()

#__getitem__

#__setitem__

#__delitem__

支持下标(或切片)操作的函数

class Fib(object):

def __getitem__(self, n):

if isinstance(n, int):

a, b = 1, 1

for x in range(n):

a, b = b, a + b

return a

if isinstance(n, slice):

start = n.start

stop = n.stop

a, b = 1, 1

L = []

for x in range(stop):

if x >= start:

L.append(a)

a, b = b, a + b

return L

fib = Fib()

print(fib[10])

print(fib[0:10])

#__getattr__

#__getattribute__

#__setattr__

#__delattr__

支持点操作(即 "对象.属性" 访问方式),

当访问不存在的属性时,才会使用__getattr__  方法。

class Student(object):

def __init__(self):

self.name = "Michael"

def __getattr__(self, attr):

print '__getattr__ called'

if attr=='score':

return 99

elif attr=='name':

return "Tom"

s = Student()

print(s.score) # 99

print(s.name) # Michael

Python的字典支持下标操作,但不支持 "." 操作,如果想让其支持,如下实现:

class Storage(dict):

__slots__ = ()

"""

A Storage object is like a dictionary except `obj.foo` can be used

in addition to `obj['foo']`.

>>> o = Storage(a=1)

>>> o.a

>>> o['a']

>>> o.a = 2

>>> o['a']

>>> del o.a

>>> o.a

Traceback (most recent call last):

...

AttributeError: 'a'

>>> 'b' in o

False

"""

def __getattr__(self, key):

try:

return self[key]

except KeyError, k:

raise AttributeError(k)

def __setattr__(self, key, value):

self[key] = value

def __delattr__(self, key):

try:

del self[key]

except KeyError, k:

raise AttributeError(k)

def __repr__(self):

return ''

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值