面向对象中特殊方法的补充、isinstance/issubclass/type、方法和函数、反射

一、面向对象中特殊方法的补充

  1.__str__  能将对象名改成你想要的字符串,但是类型还是类

class Foo(object):

    def __init__(self):
        pass

    def func(self):
        pass

    def __str__(self):
        return "f1"

obj = Foo()
print(obj,type(obj))
# f1 <class ‘__main__.Foo‘>  

  2.__doc__  能将类的注释文档显示出来

class Foo(object):
    ‘‘‘
    asdqwe
    ‘‘‘
    def __init__(self):
        pass

    def func(self):
        pass
obj = Foo()
print(obj.__doc__)
# asdqwe

  3.__dict__  能将对象中封装的数据以字典的形式输出

class Foo(object):

    def __init__(self,name,age):
        self.name = name
        self.age = age

    def func(self):
        pass

obj1 = Foo("a1",14)
obj2 = Foo("a2",15)
print(obj1.__dict__)    #{‘name‘: ‘a1‘, ‘age‘: 14}
print(obj2.__dict__)    #{‘name‘: ‘a2‘, ‘age‘: 15}

  4.__iter__  

    如果想要把不可迭代对象转变成可迭代对象:

      1.在类中定义__iter__方法

      2.iter内部返回一个迭代器(生成器也是一种特殊迭代器)

class Foo(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def func(self):
        pass
    def __iter__(self):
        return iter([11,22,33,44])
obj =   Foo("a1",13)
for el in obj:
    print(el)
# 11
# 22
# 33
# 44

几个实例:

class StarkConfig(object):
    list_display = []

    def get_list_display(self):
        self.list_display.insert(0,33)
        return self.list_display

class RoleConfig(StarkConfig):
    list_display = [11,22]

s1 = StarkConfig()

result1 = s1.get_list_display()
print(result1) # [33]

result2 = s1.get_list_display()
print(result2) # [33,33]
class StarkConfig(object):
    def __init__(self):
        self.list_display = []

    def get_list_display(self):
        self.list_display.insert(0, 33)
        return self.list_display

class RoleConfig(StarkConfig):
    list_display = [11, 22]

s1 = StarkConfig()

result1 = s1.get_list_display()
print(result1)  # [33]

result2 = s1.get_list_display()
print(result2)  # [33, 33]

二、sinstance/issubclass/type三种方法

  1.issubclass  #检查第一个参数是否是第二个参数的子类或子孙类

class Base(object):
    pass
class Foo(Base):
    pass
class Bar(Foo):
    pass
print(issubclass(Bar,Base))
print(issubclass(Foo,Base))
# True
# True

  2.type  #获取当前对象是由哪个类创建的

class Foo(object):
    pass

obj = Foo()

print(obj, type(obj))  # 获取当前对象是由那个类创建。
if type(obj) == Foo:
    print(‘obj是Foo类型‘)
# obj是Foo类型

    练习题

class Foo(object):
    pass

class Bar(object):
    pass

def func(*args):
    foo_counter = 0
    bar_counter = 0
    for item in args:
        if type(item) == Foo:
            foo_counter += 1
        elif type(item) == Bar:
            bar_counter += 1
    return foo_counter, bar_counter    #函数返回值为多个值以元组的形式返回

result = func(Foo(),Bar(),Foo())
print(result)

v1, v2 = func(Foo(), Bar(), Foo())    #解构
print(v1, v2)

  3.isinstance  判断第一个参数(对象),是否是第二个参数(类及父类)的实例

class Bar(object):
    pass
class Base(Bar):
    pass
class Foo(Base):
    pass
obj1 = Foo()
print(isinstance(obj1,Foo))
print(isinstance(obj1,Base))
print(isinstance(obj1,Bar))
# True
# True
# True

    **type:判断对象是不是由某一个指定类 type(obj)==Foo

    **isinstance:判断对象是不是由某一个指定类或其父类 isinstance(obj,Foo)

三、判断是方法还是函数

  称谓:类,方法

       外,函数

      对象.xxx---->xxx就是方法

      类.xxx   ----->xxx就是函数

      xxx  ------>xxx就是函数

    代码判断:

from types import FunctionType,MethodType
def check(arg):
    """
    检查arg是函数还是方法
    :param arg:
    :return:
    """
    if isinstance(arg,FunctionType):
        print("arg是一个函数")
    elif isinstance(arg,MethodType):
        print("arg是一个方法")
    else:
        print("arg什么都不是")
class Foo():
    def f1(self):
        pass
obj = Foo()
check(obj.f1)   #arg是一个方法
check(Foo.f1)   #arg是一个函数

四、反射

  getattr  根据字符串的形式,去对象中找成员  v = getattr(obj,"func")

  hasattr  根据字符串的形式,去判断对象中是否有成员

  setattr  根据字符串的形式,动态的设置一个成员(内存)

  delattr  根据字符串的形式,动态的删除一个成员(内存)

from types import FunctionType
import handler

while True:
    print("""
    系统支持的函数有:
        1. f1
        2. f2
        3. f3
        4. f4
        5. f5
    """)
    val = input("请输入要执行的函数:")  # val = "f1"

    # 错误
    # handler.val()
    if hasattr(handler, val):
        func_or_val = getattr(handler, val)  # 根据字符串为参数,去模块中寻找与之同名的成员。
        if isinstance(func_or_val, FunctionType):
            func_or_val()
        else:
            print(func_or_val)
    else:
        print(‘handler中不存在输入的属性名‘)

class Account(object):
    func_list = [‘login‘, ‘logout‘, ‘register‘]

    def login(self):
        """
        登录
        :return:
        """
        print(‘登录111‘)

    def logout(self):
        """
        注销
        :return:
        """
        print(‘注销111‘)

    def register(self):
        """
        注册
        :return:
        """
        print(‘注册111‘)

    def run(self):
        """
        主代码
        :return:
        """
        print("""
            请输入要执行的功能:
                1. 登录
                2. 注销
                3. 注册
        """)

        choice = int(input(‘请输入要执行的序号:‘))
        func_name = Account.func_list[choice - 1]

        # func = getattr(Account,func_name) # Account.login
        # func(self)

        func = getattr(self, func_name)  # self.login
        func()

obj1 = Account()
obj1.run()

obj2 = Account()
obj2.run()

callable  判断是否能被调用

原文地址:https://www.cnblogs.com/qq849784670/p/9561362.html

时间: 2024-10-09 08:34:14

面向对象中特殊方法的补充、isinstance/issubclass/type、方法和函数、反射的相关文章

对php面向对象中魔术方法的认识

<?php//header(charset="utf8");    //echo 'hey 这里是描述我对php 面向对象中各种魔术方法的认识.';/* *魔术方法是在一些特定情况下会自动调用的一些php系统自定义函数 *这些函数都很有个性,他们统一以__两个 _ (下划线)开头. * 下面对于php 中这些常用的魔术方法一些个人认识. **/class demo {    public $name;    public $age; //当实例化这个类,首先会自动调用的方法 __

面向对象中的常用魔术方法

__autoload($classname);这个魔术方法与其他魔术方法不同的是,它不是在类中使用的,其他都是在类内部使用,只要在页面中用到一个类,就会自动将这个类名传给这个函数的参数.在开发中用它来自动加载类. __sleep():是在对象序列化也叫串行化时,自动调用的方法,因为对象序列化的时候serialize($object),如果类里不加这个魔术方法,会自动将类中的所有属性全部序列化,如果只想让某些属性被序列化,就要用到这个方法,这个方法返回一个由类的属性组成的数组.序列哪个属性就将那个

面向对象中的特殊的成员修饰符和几个特殊的方法

面向对象的成员修饰符 #Auther Bob #--*--conding:utf-8 --*-- # 成员修饰符 # 共有成员 # 私有成员 # 1.私有字段 # 私有的普通字段 # 私有的静态字段 # 2.私有方法 # 私有的方法 # 默认情况下,类的字段和方法都是共有的,通过对象和类就直接可以访问,但是如果我们在字段或者方法名字的前面加2个下划线,那么我们就不能在外部访问这些字段和方法,这些 # 方法和字段只能内部方法 class person(object): name = "diandi

java面向对象中的方法重载与方法重写的区别

一.方法重载(overload) a:一个类中允许声明多个方法 b:一个类中允许有多个方法名称一样,但是参数不同的多个方法.通过参数不同来区别不同的方法. 参数不同表现为: 1:参数个数不同 2:参数类型不同 3:参数类型的顺序不同也是参数类型不同 4:在参数类型一样的情况下,名称不一样不代表参数不一样 重载方法的调用: 1:根据调用的时候实际参数来判断到底调用的是哪一方法 2:根据参数的要求,严格匹配传入的对应类型 3:如果严格匹配不到的话,默认遵循就近匹配 4:根据数据默认转换的顺序就近匹配

面向对象中对象和类以及如何访问类中属性和方法

对象:客观存在的具体事物.某一个具体的个体 *类:具有相同行为和共同特征的对象的集合,类是人类脑海中一个抽象的概念,通过类创建对象 *类中的成员:1.成员属性(描述外部特征) 2.成员方法(描述功能行为)* 如何定义一个类: * [修饰符] class 类名{ * //1.属性的定义:与定义变量类似 * [修饰符] 数据类型 属性名; * //2.方法的定义 * [修饰符] 返回值类型 方法名(形参列表){ * //方法体; * } * } * 成员变量和局部变量的区别: * 1.作用域不同:成

面向对象中:变量,方法,属性相关知识及示例

变量: 实例变量(字段): class Foo: def __init__(self,name,age): self.__name = name #私有实例变量,只能内部调用,外部不能调用,子类不能调用 self.age = age #公有实例变量,都可以调用 def func(self): pass类变量(静态字段): class Foo: __race = '人类' #私有静态字段,只能内部调用,外部不能调用,子类不能调用 country = '中国' #公有静态字段 def __init_

面向对象中的双下方法

1.__str__与__repr__方法 class Animal: def __init__(self,name,age): self.name = name self.age = age def f(self): print("这是父类的方法") class Persion(Animal): country = "chinese" def __init__(self,name,age,sex): Animal.__init__(self,name,age) se

python学习笔记之面向对象中的静态方法、类方法、属性方法总结

静态方法 类方法 属性方法 一.静态方法 可以利用@staticmethod装饰器把一个方法变成一个静态方法.静态方法不可以方法实例变量或者类变量,也就是说不可以使用self.属性这样子调用实例属性了.其实静态方法就和类本身没什么关系了,它和类 唯一的关联就是需要通过类名来调用这个方法. 错误调用方式: class Dog(object): def __init__(self,name): self.name = name @staticmethod #把eat方法变为静态方法 def eat(

Python全栈--9.1--面向对象进阶-super 类对象成员--类属性- 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理

上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象,根据模板创建的实例(即:对象),实例用于调用被包装在类中的函数 面向对象三大特性:封装.继承和多态 本篇将详细介绍Python 类的成员.成员修饰符.类的特殊成员. 注意点: self ,我们讲过了,self = 对象,实例化后的对象调用类的各种成员的时候的self就是这个对象. 而且我们也讲过了