what' the python之面向对象(进阶)

面向对象的知识点补充(进阶版)

classmethod和staticmethod:这两个函数的用途就是可以不用实例化对象就可以调用方法

class Classmethod_Demo():
    role = ‘dog‘

    @classmethod
    def func(cls):
        print(cls.role)

Classmethod_Demo.func()

class Staticmethod_Demo():
    role = ‘dog‘

    @staticmethod
    def func():
        print("当普通方法用")

Staticmethod_Demo.func()

isinstance和issubclass

  isinstance是用来检查实例化的对象是否是由想检查的类实例化出来的,返回的是布尔值。isinstance(obj,t)

class Fruit:
    def __init__(self,name):
        self.name=name

class Vegetable:
    def __init__(self,name):
        self.name=name

b=Fruit(‘banana‘)
print(isinstance(b,Fruit))#True
print(isinstance(b,Vegetable))#False

  issubclass是用来检查一个类是否是想检查的类的子类,返回的是布尔值。issubclass(cls,classinfo)

class Plant:
    def __init__(self,name):
        self.name=name

class Fruit(Plant):
    def __init__(self,name):
        self.name=name

class Vegetable:
    def __init__(self,name):
        self.name=name

print(issubclass(Fruit,Plant))#True
print(issubclass(Fruit,Vegetable))#False

反射

python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

四个可以实现自省的函数:hasattr,getattr,setattr,delattr(后面两个不常用,平时不推荐使用)

上述四个函数适用于类和对象(一切皆对象,类本身也是一个对象)

下面用代码来提现每个函数的作用:

class Sport:
    def __init__(self,name,place):
        self.name=name
        self.place=place
    def play(self):
        print(‘i like %s‘%self.name)
    def where(self):
        print(‘we play at %s‘%self.place)

bas=Sport(‘basketball‘,‘ground‘)
#hasattr#查看属性,返回布尔值
print(hasattr(bas,‘name‘))#检测是否有属性,输出布尔值

#getattr#得到属性,可以调用方法
print(getattr(bas,‘where‘))#检测是否有属性,输出的是方法的内存地址
n=getattr(bas,‘where‘)
print(n)#检测是否有属性,与上面一个print里的内容一模一样,输出的是方法的内存地址
func=getattr(bas,‘where‘)
func()#调用方法,输出为we play at ground
# print(getattr(bas,‘price‘))#不存在即报错
print(getattr(bas,‘price‘,‘不存在啊‘))#设置默认值即不报错,输出默认值

#setattr可以更改属性,不推荐使用
setattr(bas,‘price‘,100)#新设置一个属性
print(bas.price)
setattr(bas,‘show_name‘,lambda self:self.name+‘ good‘)
print(bas.show_name(bas))#basketball good

#delattr#删除属性,不推荐使用
delattr(bas,‘place‘)
# delattr(bas,‘name111‘)#不存在,则报错
print(bas.__dict__)

类也是对象,自然也可以使用上述函数:

class Foo(object):

    staticField = "old boy"

    def __init__(self):
        self.name = ‘alex‘

    def func(self):
        return ‘func‘

    @staticmethod
    def bar():
        return ‘bar‘

print getattr(Foo, ‘staticField‘)
print getattr(Foo, ‘func‘)
print getattr(Foo, ‘bar‘)

也可以用来反射当前模块成员:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import sys
def s1():
    print ‘s1‘
def s2():
    print ‘s2‘

this_module = sys.modules[__name__]
hasattr(this_module, ‘s1‘)
getattr(this_module, ‘s2‘)

导入其他模块,利用反射查找该模块是否存在某个方法

#文件一
#!/usr/bin/env python
# -*- coding:utf-8 -*-

def test():
    print(‘from the test‘)

#文件二
#!/usr/bin/env python
# -*- coding:utf-8 -*-

"""
程序目录:
    module_test.py
    index.py

当前文件:
    index.py
"""

import module_test as obj

#obj.test()

print(hasattr(obj,‘test‘))

getattr(obj,‘test‘)()

以下内容供进阶了解

__str__、__repr__、__format__、__del__、__call__、__len__、__hash__、__eq__、__item__系列

改变对象的字符串显示__str__,__repr__

自定制格式化字符串__format__

#_*_coding:utf-8_*_

format_dict={
    ‘nat‘:‘{obj.name}-{obj.addr}-{obj.type}‘,#学校名-学校地址-学校类型
    ‘tna‘:‘{obj.type}:{obj.name}:{obj.addr}‘,#学校类型:学校名:学校地址
    ‘tan‘:‘{obj.type}/{obj.addr}/{obj.name}‘,#学校类型/学校地址/学校名
}
class School:
    def __init__(self,name,addr,type):
        self.name=name
        self.addr=addr
        self.type=type

    def __repr__(self):
        return ‘School(%s,%s)‘ %(self.name,self.addr)
    def __str__(self):
        return ‘(%s,%s)‘ %(self.name,self.addr)

    def __format__(self, format_spec):
        # if format_spec
        if not format_spec or format_spec not in format_dict:
            format_spec=‘nat‘
        fmt=format_dict[format_spec]
        return fmt.format(obj=self)

s1=School(‘oldboy1‘,‘北京‘,‘私立‘)
print(‘from repr: ‘,repr(s1))#from repr:  School(oldboy1,北京)
print(‘from str: ‘,str(s1))#from str:  (oldboy1,北京)
print(s1)#(oldboy1,北京)

‘‘‘
str函数或者print函数--->obj.__str__()
repr或者交互式解释器--->obj.__repr__()
如果__str__没有被定义,那么就会使用__repr__来代替输出
注意:这俩方法的返回值必须是字符串,否则抛出异常
‘‘‘
print(format(s1,‘nat‘))#oldboy1-北京-私立
print(format(s1,‘tna‘))#私立:oldboy1:北京
print(format(s1,‘tan‘))#私立/北京/oldboy1
print(format(s1,‘asfdasdffd‘))#oldboy1-北京-私立
class B:
     def __str__(self):
         return ‘str : class B‘

     def __repr__(self):
         return ‘repr : class B‘

b=B()
print(‘%s‘%b)#repr : class B
print(‘%r‘%b)#str : class B

__del__

析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

class Foo:
    def __del__(self):
        print(‘执行我啦‘)
f1=Foo()
del f1
print(‘------->‘)

#输出结果
执行我啦
------->

__call__

对象后面加括号,触发执行。

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Foo:
    def __init__(self):
        pass
    def __call__(self, *args, **kwargs):
        print(‘__call__‘)

obj = Foo() # 执行 __init__
obj()       # 执行 __call__

__len__

相当于内置的len()方法,纯粹检查长度

class A:
    def __init__(self):
        self.a = 1
        self.b =‘b‘

    def __len__(self):
        return len(self.__dict__)
a = A()
print(len(a))#2  其实电泳len方法的时候就是python在内部实现了__len__

__hash__

查看是否可以hash

class A:
    def __init__(self):
        self.a = 1
        self.b = 2

    def __hash__(self):
        return hash(str(self.a)+str(self.b))
a = A()
print(hash(a))#其实调用hash方法的时候就是内部实现了__hash__

__eq__

class A:
    def __init__(self):
        self.a = 1
        self.b = 2

    def __eq__(self,obj):
        if  self.a == obj.a and self.b == obj.b:
            return True
a = A()
b = A()
print(a == b)#True

__item__系列:__getitem__、__setitem__、__delitem__

class Foo:
    def __init__(self,name):
        self.name=name

    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)

f1=Foo(‘sb‘)
f1[‘age‘]=18
f1[‘age1‘]=19
del f1.age1
del f1[‘age‘]
f1[‘name‘]=‘alex‘
print(f1.__dict__)

最后给两道大题压压惊

一、曾经的一道面试题:

class Person:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def __hash__(self):
        return hash(self.name+self.sex)

    def __eq__(self, other):
        if self.name == other.name and self.sex == other.sex:return True
#创建的对象中只要名字和性别相同,就认为是两个相同的类

p_lst = []
for i in range(84):
    p_lst.append(Person(‘egon‘,i,‘male‘))#将84个egon传入列表中

print(p_lst)
print(set(p_lst))#set是集合,具有去重功能,其实质就是在内部实现了__hash__和__eq__方法

二、纸牌游戏题:

from collections import namedtuple
Cards=namedtuple(‘Cards‘,[‘ranks‘,‘suit‘])
class FranchDeck:
    ranks = [str(n) for n in range(2,11)] + list(‘JQKA‘)
    suits = [‘红心‘,‘方板‘,‘梅花‘,‘黑桃‘]

    def __init__(self):
        self._cards = [Cards(rank,suit) for rank in FranchDeck.ranks
                                        for suit in FranchDeck.suits]

    def __len__(self):
        return len(self._cards)

    def __getitem__(self, item):
        return self._cards[item]

    def __setitem__(self, key, value):
        self._cards[key] = value

deck = FranchDeck()
print(deck[0])#Cards(ranks=‘2‘, suit=‘红心‘)Cards(ranks=‘2‘, suit=‘红心‘)
from random import choice#随机取值,choice依赖于内置的__getitem__
print(choice(deck))#Cards(ranks=‘J‘, suit=‘黑桃‘)
print(choice(deck))#Cards(ranks=‘2‘, suit=‘红心‘)

from random import shuffle#洗牌,shuffle依赖于__getitem__和__setitem__
shuffle(deck)
print(deck[:5])#[Cards(ranks=‘Q‘, suit=‘方板‘), Cards(ranks=‘2‘, suit=‘黑桃‘), Cards(ranks=‘5‘, suit=‘梅花‘), Cards(ranks=‘4‘, suit=‘方板‘), Cards(ranks=‘2‘, suit=‘梅花‘)]

what' the python之面向对象(进阶)

原文地址:https://www.cnblogs.com/zhuminghui/p/8227893.html

时间: 2024-10-29 04:36:32

what' the python之面向对象(进阶)的相关文章

Python之面向对象进阶

Python之面向对象进阶 进阶有:Python 类的成员.成员修饰符.类的特殊成员. 一.类的成员 类的成员可以分为三大类:字段.方法和属性. 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段.而其他的成员,则都是保存在类中,即:无论对象的多少,在内存中只创建一份. 1.字段 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同, 普通字段属于对象 静态字段属于类 1 class Province:

Python基础-面向对象进阶

面向对象进阶 一 类中的装饰器方法  classmethod staticmethod property 1.1 property 一般情况下,方法都是动词.指某一类事物的动作 在计算圆形的周长和面积的时候,他们应该是圆形的属性,但是这里确是一个方法.这不符合python面向对象(能够完全区分属性和方法)的理念. 所以我们可以用一个装饰器去将一个属性性质的函数,装饰成一个属性.可以以调用属性的方式去调用他. from math import pi class Circle: def __init

Python【day7】:Python学习(面向对象进阶、反射、socket介绍)

面向对象进阶 1.类变量和实例变量 # 一.变量 # 变量包括:实例变量和类变量, # 他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同, # 实例变量属于对象 # 类变量属于类 class Province(object): country = "中国" #类变量 def __init__(self, name): self.name = name # 实例变量 # 直接访问实例变量(实例名来调用) obj = Province('河北省') print(obj.na

Python之面向对象进阶------反射(Day26)

一 classmethod class Classmethod_Demo(): role = 'dog' @classmethod def func(cls): print(cls.role) Classmethod_Demo.func() staticmethod class Staticmethod_Demo(): role = 'dog' @staticmethod def func(): print("当普通方法用") Staticmethod_Demo.func() clas

python:面向对象进阶

1,反射 反射:使用字符串类型的名字去操作变量 反射就没有安全问题,去操作内存中已经存在的变量 #反射对象中的属性和方法 class A: price=20 print(getattr(A,'price')) #反射对象的属性 class A: def func(self): print('in func') a =A() a.name ='alex' ret =getattr(a,'name')#通过变量名的字符串形式取到的值 print(ret) #反射对象的方法 ret =getattr(

13、Python之面向对象进阶篇

1.静态方法 静态方法是指可以被类直接调用的方法,其类似于静态属性,其既可以被类直接调用,也可以被对象调用.在python中使用装饰器@staticmethod来申明某个方法为静态方法,静态方法的实例代码如下: 1 class Grade(object): 2 def __init__(self,name,count): 3 self.__name = name 4 self.__count = count 5 @staticmethod #申明为静态方法 6 def print_grade(

Python之路【第八篇】:Python基础(24)——面向对象进阶

参考连接: Python 面向对象(初级篇) http://www.cnblogs.com/wupeiqi/p/4493506.html python 面向对象(进阶篇) http://www.cnblogs.com/wupeiqi/p/4493506.html python 面向对象及相关 http://www.cnblogs.com/wupeiqi/articles/5017742.html 面向对象进阶: 类成员之字段.方法.属性: 类成员修饰符: 类成员之特殊成员 1.类方法 普通的方法

Python基础—面向对象(进阶篇)

通过上一篇博客我们已经对面向对象有所了解,下面我们先回顾一下上篇文章介绍的内容: 上篇博客地址:http://www.cnblogs.com/phennry/p/5606718.html 面向对象是一种编程方式,此编程方式的实现是基于对类和对象的使用: 类是一个模版,模板中包装了多个方法供使用(这里方法就是函数): 对象,根据模板创建的实例,实例用于调用被包装在类中的函数: 面向对象的三大特性:封装.继承.多态. 今天博客的内容主要介绍:Python类的成员.成员修饰符.类的特殊成员.异常处理和

Python面向对象进阶和socket网络编程-day08

写在前面 上课第八天,打卡: 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __init__(self,name): self.name=name p = Chinese('standby') # 实例化一个对象 print(p) # 打印这个对象 --- <__main__.Chinese object at 0x0000000000B3A978> - 示例2: >&g

python面向对象进阶版

面向对象基础知识: 1.面向对象是一种编程方式,此编程方式的实现是基于对类和对象的使用: 2.类是一个模板,模板中包装了多个'函数'供使用(可以将多函数中公用的变量封装到对象中): 3.对象,根据模板创建的实例(即:对象),实例用于被包装在类中的函数: 4.面向对象三大特性:封装.继承和多态. 面向对象进阶篇详细介绍python类的成员.成员修饰符和类的特殊成员. 类的成员 类的成员可以分为三大类:字段.方法和属性 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存