常用内建属性
class
用于查看当前对象所属的类
>>> age = 35
>>> age.__class__
<type 'int'>
>>> name = 'bob'
>>> name.__class__
<type 'str'>
>>> def foo(): pass
>>>foo.__class__
<type 'function'>
>>> class Bar(object): pass
>>> b = Bar()
>>> b.__class__
<class '__main__.Bar'>
slots
- 动态语言:可以在运行的过程中,修改代码
- 静态语言:编译时已经确定好代码,运行过程中不能修改
如果我们想要限制实例的属性怎么办?比如,只允许对Person实例添加name和age属性。
为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:
>>> class Person(object):
__slots__ = ("name", "age")
>>> P = Person()
>>> P.name = "老王"
>>> P.age = 20
>>> P.score = 100
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
AttributeError: Person instance has no attribute 'score'
>>>
注意:
- 使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的
In [67]: class Test(Person):
...: pass
...:
In [68]: t = Test()
In [69]: t.score = 100
doc
表示类的描述信息
class Foo:
""" 描述类信息,这是用于看片的神奇 """
def func(self):
pass
print(Foo.__doc__)
#输出:类的描述信息
module
module 表示当前操作的对象在那个模块
test.py
class Person(object):
def __init__(self):
self.name = 'laowang'
main.py
from test import Person
obj = Person()
print(obj.__module__) # 输出 test 即:输出模块
print(obj.__class__) # 输出 test.Person 即:输出类
dict
类或对象中的所有属性
类的实例属性属于对象;类中的类属性和方法等属于类,即:
class Province(object):
country = 'China'
def __init__(self, name, count):
self.name = name
self.count = count
def func(self, *args, **kwargs):
print('func')
# 获取类的属性,即:类属性、方法、
print(Province.__dict__)
# 输出:
# {'__dict__': <attribute '__dict__' of 'Province' objects>,
# '__module__': '__main__',
# 'country': 'China',
# '__doc__': None,
# '__weakref__': <attribute '__weakref__' of 'Province' objects>,
# 'func': <function Province.func at 0x101897950>,
# '__init__': <function Province.__init__ at 0x1018978c8>}
# 获取对象的属性
obj1 = Province('山东', 10000)
print(obj1.__dict__)
# 获取 对象obj1 的属性
# 输出:{'count': 10000, 'name': '山东'}
obj2 = Province('山西', 20000)
print(obj2.__dict__)
# 获取 对象obj1 的属性
# 输出:{'count': 20000, 'name': '山西'}
内建属性集合
getattribute 用法和坑
例子
class Itcast(object):
def __init__(self,subject1):
self.subject1 = subject1
self.subject2 = 'cpp'
#属性访问时拦截器,打log
def __getattribute__(self,obj):
if obj == 'subject1':
print('log subject1')
return 'redirect python'
else: #测试时注释掉这2行,将找不到subject2
return object.__getattribute__(self,obj)
def show(self):
print('this is Itcast')
s = Itcast("python")
print(s.subject1)
print(s.subject2)
运行结果
log subject1
redirect python
cpp
有可能写出来的坑
class Person(object):
def __getattribute__(self,obj):
print("---test---")
if obj.startswith("a"):
return "hahha"
else:
return self.test
def test(self):
print("heihei")
t.Person()
t.a #返回hahha
t.b #会让程序死掉
"""
原因是:当t.b执行时,会调用Person类中定义的__getattribute__方法,
但是在这个方法的执行过程中if条件不满足,所以, 程序执行else里面的代码,即return self.test
问题就在这,因为return 需要把self.test的值返回,那么首先要获取self.test的值,因为self此时就是t这个对象,
所以self.test就是t.test 此时要获取t这个对象的test属性,那么就会跳转到__getattribute__方法去执行,
即此时产生了递归调用,由于这个递归过程中 没有判断什么时候推出,所以这个程序会永无休止的运行下去,
又因为每次调用函数,就需要保存一些数据,那么随着调用的次数越来越多,最终内存吃光,所以程序 崩溃
注意:以后不要在__getattribute__方法中调用self.xxxx
"""
mro
类名.__mro__
可以查看C类的对象搜索方法时的先后顺序 ,通过C3算法给出先后的继承顺序
转载:https://blog.csdn.net/YiJie__ShuSheng/article/details/105385566
查看评论