二十六. Python基础(26)--类的内置特殊属性和方法

● 知识框架

● 类的内置方法/魔法方法案例1: 单例设计模式

# 类的魔法方法

# 案例1: 单例设计模式

class Teacher:             #创建一个老师类

    __isinstance = None     #创建一个私有静态变量, 准备用来指向一个裸着的对象

    def __new__(cls, *args, **kwargs): #创建一个裸着的对象

        if not cls.__isinstance:         #如果__isinstance属性为None

            cls.__isinstance = object.__new__(cls) #用object.__new__创建一个裸着的对象

        return cls.__isinstance         #返回一个对象

    def __init__(self,name,cloth):     #self就是cls.__isinstance返回的对象

        self.name = name                 #给self的name属性赋值

        self.cloth = cloth             #给self的cloth属性赋值

p1 = Teacher('Arroz','white')

print(p1.name)

p2 = Teacher('Paul','black')

p3 = Teacher('Paul','black')

print(p1.name)

print(p2)

print(p3)

● 类的内置方法/魔法方法案例2: 综合案例

# 案例2: 综合案例

class Person:

# __init__是在类实例创建之后调用,而 __new__方法正是创建这个类实例的静态方法

    def __new__(cls, *args, **kwargs): # __new__()方法的第一个参数必须是当前类cls(也可以用其它名字,但习惯写成cls),后续参数则可以自由指定

        print('__new__')

return object.__new__(cls) # object可以用其它新式类代替, 但不要写本类(如这里的Person)

# 我们可以自由选择任意一个的其他的新式类(必定要是新式类,只有新式类必定都有new(),因为所有新式类都是object的后代,而经典类则没有new() 方法)的new()方法来制造实例,包括这个新式类的所有前代类和后代类,只要它们不会造成递归死循环。

# __new__()用来创建实例, 在返回的实例上执行__init__()方法. 当__new__()的参数是当前类时(可以写成__new__(cls), 或者__new__(Person)), __init__()方法才会自动执行, 否则, 如果参数是其它类, __init__()不执行

#还可以写成: return super().__new__(cls)或return super(Person, cls).__new__(cls)

# __new()__是生产部经理,它以决定是否将原料提供给该生产部工人,即init()

    def __init__(self,name,age,sex): # 构造方法, __init__()方法的第一个参数必须是当前类的对象self(也可以用其它名字,但习惯写成self),后续参数则可以自由指定

        self.name=name

self.age=age

self.sex=sex

def __hash__(self):

return hash(self.name+self.sex) # 将self.name和self.sex两个字符串结合, 作为hash()的实参

    def __eq__(self, other):

if self.name==other.name and self.sex==other.sex:return True

def __str__(self): # 定义当被str()调用时的行为, 定以后, print(对象)相当于 对象.__str__()

return self.name+", "+self.sex

def __repr__(self):

return repr(self.name+", "+self.sex)

def __call__(self,x,y):

return x*y

def __len__(self):

return len(self.__dict__)

def __getitem__(self, item):

print(self.__dict__[item])

def __setitem__(self, key, value):

self.__dict__[key]=value

def __delitem__(self, key):

print('del obj[key]时,我执行')

self.__dict__.pop(key)

def __delattr__(self, item):

print('del obj.key时,我执行')

self.__dict__.pop(item)

def __del__(self):

print('__del__')

p1=Person('Arroz',20,'Male')

p2=Person('Arroz',30,'Male')

p3=Person('Arroz',40,'Male')

p4=Person('Arroz',50,'Female')

p_lst=[p1,p2,p3,p4] # 三个对象的地址不同, 但值相同

print(set(p_lst))

print('-------------------')

print(p1)

print(str(p1))

print(repr(p1))

print('-------------------')

print(p1(3,7))

print('-------------------')

print(len(p1))

print('-------------------')

print('before:', p4.__dict__)

p4['age']=60 #与魔法方法__setitem__()相关

p4['hobby']='swimming'

print('after1:', p4.__dict__)

del p4.hobby

del p4['age']

p4['name']='Alex'

print('after2:', p4.__dict__)

print('-------------------')

# 反射:通过字符串操作对象的相关属性

print(hasattr(p4,'name'))

print(getattr(p4,'name'))

setattr(p4,'Nationality','China')

delattr(p4,'name')

print(p4.__dict__)

'''

如果没有定义__str__()和__repr__(), 那么打印结果是各对象的地址, 例如:

{<__main__.Person object at 0x000000000265B9E8>, <__main__.Person object at 0x000000000265B940>}

'''

__new__

__new__

__new__

__new__

{'Arroz, Female', 'Arroz, Male'}

-------------------

Arroz, Male

Arroz, Male

'Arroz, Male'

-------------------

21

-------------------

3

-------------------

before: {'name': 'Arroz', 'age': 50, 'sex': 'Female'}

after1: {'name': 'Arroz', 'age': 60, 'sex': 'Female', 'hobby': 'swimming'}

del obj.key时,我执行

del obj[key]时,我执行

after2: {'name': 'Alex', 'sex': 'Female'}

-------------------

True

Alex

del obj.key时,我执行

{'sex': 'Female', 'Nationality': 'China'}

__del__

__del__

__del__

__del__

● 类的内置方法/魔法方法案例3: 斐波那契数列数列

# 案例3: 斐波那契数列

# 一个实现了__iter__()和__next__()方法的类可以作为迭代器使用。

# __next__方法:返回迭代器的下一个元素(py2中是next())

# __iter__方法:返回迭代器对象本身

class Fib(object):

def __init__(self):

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

    def __iter__(self):

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

    def __next__(self): # py2中是next()

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

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

            raise StopIteration();

return self.a # 返回下一个值

# Fib()是一个生成器

print([i for i in Fib()]) # [1, 1, 2, 3, 5, 8]

print(list(Fib())) # [1, 1, 2, 3, 5, 8]

● 元类

● 元类案例

print('1. Metaclass declaration')

class Meta(type):

def __init__(cls, name, bases, attrd):

super(Meta, cls).__init__(name, bases, attrd)

print('3. Create class %r' % (name))

print('2. Class Foo declaration')

class Foo(metaclass = Meta):

def __init__(self):

print('*. Init class %r' % (self.__class__.__name__))

class Child(Foo):

pass

print('4. Class Foo f1 instantiation')

f1 = Foo()

print('5. Class Foo f2 instantiation')

f2 = Foo()

'''

1. Metaclass declaration

2. Class Foo declaration

3. Create class 'Foo'

3. Create class 'Child'

4. Class Foo f1 instantiation

*. Init class 'Foo'

5. Class Foo f2 instantiation

*. Init class 'Foo'

'''

print(type(Meta)) # <class 'type'>

print(Meta.__class__) # <class 'type'>

print(type(Foo)) # <class '__main__.Meta'>

print(Foo.__class__) # <class '__main__.Meta'>

print(type(Child)) # <class '__main__.Meta'>

print(Child.__class__) # <class '__main__.Meta'>

class Te(object):

def __new__(cls,a,b):

print('__new__', a,b)

return object.__new__(cls)

def __init__(self,a,b):

print("this is a test")

print('__init__', a, b)

a = Te(12,23)

'''

__new__ 12 23

this is a test

__init__ 12 23

'''

# 不能写class Te(type), 因为type是一个meta class,不是class,所以class不能继承于type

● 元类的声明

# 声明元类的方法:

class Foo(object): #py2

    __metaclass__ = something

class Foo(metaclass=something): #py3

● 类的方法的装饰器

# 装饰器在类中

class A(object):

def outer(func):

def inner(self):

print("222")

r = func(self)

print("333")

return r

return inner

@outer

def f(self):

print("000")

obj = A()

obj.f()

print("================")

# 装饰器不在类中

def outer(func):

def inner(self):

print("222")

r = func(self)

print("333")

return r

return inner

class S(object):

@outer

def f(self):

print("000")

a = S()

a.f()

222

000

333

================

222

000

333

二十六. Python基础(26)--类的内置特殊属性和方法的更多相关文章

  1. Js基础知识7-JavaScript所有内置对象属性和方法汇总

    对象什么的,程序员可是有很多呢... JS三大对象 对象,是任何一个开发者都无法绕开和逃避的话题,她似乎有些深不可测,但如此伟大和巧妙的存在,一定值得你去摸索.发现.征服. 我们都知道,JavaScr ...

  2. 二十四. Python基础(24)--封装

    二十四. Python基础(24)--封装 ● 知识结构   ● 类属性和__slots__属性 class Student(object):     grade = 3 # 也可以写在__slots ...

  3. 二十五. Python基础(25)--模块和包

    二十五. Python基础(25)--模块和包 ● 知识框架   ● 模块的属性__name__ # my_module.py   def fun1():     print("Hello& ...

  4. 十六. Python基础(16)--内置函数-2

    十六. Python基础(16)--内置函数-2 1 ● 内置函数format() Convert a value to a "formatted" representation. ...

  5. python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码

    python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码 python的json.dumps方法默认会输出成这种格式"\u535a\u ...

  6. python基础12_匿名_内置函数

    一个二分查找的示例: # 二分查找 示例 data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35, 36, ...

  7. Python进阶-XVIV 类的内置方法:__str__ 、__repr__、析构函数(__del__)、双下的call,eq,new,hash 以及item相关的三个方法

    类的内置方法 它与内置函数有紧密的联系,有的内置函数就是调用的内置方法. 在顶级父类obj中有: 两个双下方法 obj.__str__ str(obj) obj.__repr__ repr(obj) ...

  8. python - 数据描述符(class 内置 get/set/delete方法 )

    数据描述符(class 内置 get/set/del方法 ): # 什么是描述符 # 官方的定义:描述符是一种具有“捆绑行为”的对象属性.访问(获取.设置和删除)它的属性时,实际是调用特殊的方法(_g ...

  9. python基础(26):类的成员(字段、方法、属性)

    1. 字段 字段:包括普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同. 普通字段属于对象 静态字段属于类 字段的定义和使用: class Province: # ...

随机推荐

  1. SQL Server 百万级数据提高查询速度的方法(转)

    1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描.2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及 ...

  2. MyBatis基础入门《二十》动态SQL(foreach)

    MyBatis基础入门<二十>动态SQL(foreach) 1. 迭代一个集合,通常用于in条件 2. 属性 > item > index > collection : ...

  3. Mysql授权root用户远程登录

    默认情况下Mysql的root用户不支持远程登录,使用以下命令授权   [Charles@localhost ~]$ mysql -uroot -p123 MariaDB [(none)]> u ...

  4. docker容器与大数据组件的冲突点

    1.容器里面安装spark,外面的程序(安装spark主机的容器)会连接不上集群.理由:这个组件用的akka,连接上集群,会提示: akka.ErrorMonitor: dropping messag ...

  5. CSS 标签选择器

    CSS 标签选择器 再<stype>标签内,通过指定输入标签来配置CSS样式 <html> <head> <!-- style 设置头部标签--> &l ...

  6. Linux 系统安全设置

    一.SElinux安全子系统策略. 临时修改 命令:setenforce 0 #临时关闭selinux. 命令:setenforce 1 #临时开启selinux 命令:getenforce      ...

  7. docker之Dockerfile实践

    上一篇介绍了Dockerfile中使用的指令,现在开始进行指令实践 先查看下本地的镜像,选一个作为base image: [root@docker ~]# docker images REPOSITO ...

  8. Bitmap的秘密

    作者: 周海鹏  来源: infoQ  发布时间: 2015-02-13 11:26  阅读: 4999 次  推荐: 10   原文链接   [收藏] 之前已经参加过几次QCon峰会,不过今年QCo ...

  9. Linux内核 kmalloc, kzalloc & devm_kzalloc 区别【转】

    本文转载自:https://blog.csdn.net/u014628531/article/details/50711409 首先,kzalloc()实现了kmalloc()+memset()的功能 ...

  10. Python入门 io篇

    简单demo with open('d:/pydemo/pythonStart/fun1.py', 'r') as f: #print(f.read()) while True: line = f.r ...