对特殊成员的补充;isinstance/issubclass/type;方法和函数的区分;反射;小知识点补充

一.对特殊成员的补充

1.__str__

如果一个类中定义了__str__方法,那么在打印对象是,默认输出该方法的返回值

# __str__
class Foo:
    def __init__(self):
        pass

    def func(self):
        pass

    def __str__(self):
        return 'F1'

obj = Foo()
print(obj,type(obj))

结果:
F1 <class '__main__.Foo'>
__str__

2.__doc__

表示类的描述信息

# __doc__
class Foo:
    """
    娃哈哈
    """
    def __int__(self):
        pass

    def func(self):
        pass

    def __str__(self):
        return 'F1'

obj = Foo()
print(obj.__doc__)

结果:

    娃哈哈
    
__doc__

3.__dict __

类或对象中的所有成员

类的普通字段属于对象;类中的静态字段和方法等属于类

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

    def func(self):
        pass

obj = Foo('剑豪',23)
obj1 = Foo('剑圣',34)

print(obj.__dict__)     # 获取对象obj的成员
print(obj1.__dict__)    # 获取对象obj1的成员

结果:
{'name': '剑豪', 'age': 23}
{'name': '剑圣', 'age': 34}
__dict__

4.__iter__

用于迭代器,之所以列表,字典,元组可以进行for循环,是因为类型内部定义了__iter__

# __iter__
# l1是list类的一个对象,可迭代对象
l1 = [11,22,33,44]

# l2是list类的一个对象,可迭代对象
l2 = [1,2,3,4]

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

    def func(self):
        pass

    def __iter__(self):
        return iter([11,22,33,44,55,66,7])
        
        #
        # yield 123
        # yield 456
        # yield 789

# obj1是Foo类的一个对象,可迭代对象
"""
如果想要把不可迭代对象 -> 可迭代对象
1. 在类中定义__iter__方法
2. iter内部返回一个迭代器(生成器也是一种特殊迭代器)
"""

obj = Foo('盖伦',23)

for item in obj:
    print(item)

结果:
11
22
33
44
55
66
7
__iter__

5.突然想起一道题

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

结果:
[33]
[33,33]
我看到的,绝对想不到

6.嘿嘿,还有一题

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

结果:
[33]
[33,33]
跟上一题答案一样,敲黑板

7.跟前两题差不多,好好看啊

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()
s2 = StarkConfig()

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

result2 = s2.get_list_display()
print(result2)  # 33

结果:
[33]
[33]
注意,答案不同了

8.给前几题来个总结:

(1).注意创建的对象

(2).注意上面的类的静态变量

二.issubclass/type/isinstance/

1.issubclass

检查第一个参数是不是第二个参数的子子孙孙类

# issubclass
class Foo(object):
    pass

class Base(Foo):
    pass

class Bar(Base):
    pass

print(issubclass(Bar,Foo))  # 检查第一个参数是否是第二个参数的 子子孙孙类

结果:
True
issubclass

2.type

获取当前对象是由哪个类创建的

# type
class Foo(object):
    pass

obj = Foo()

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

结果:
<class '__main__.Foo'>
obj是Foo类型
type
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)

结果:
(2,1)
来个练习

3.isinstance

检查第一个参数(对象)是否是第二个参数的(类或父亲)

# isinstance
class Foo(object):
    pass

class Base(Foo):
    pass

obj = Base()
print(isinstance(obj,Base)) # 检查第一个参数(对象)是否是第二个参数(类及父类)的实例。
print(isinstance(obj,Foo))  # 检查第一个参数(对象)是否是第二个参数(类及父类)的实例。

obj1 = Foo()
print(isinstance(obj1,Base)) # 检查第一个参数(对象)是否是第二个参数(类及父类)的实例。
print(isinstance(obj1,Foo))  # 检查第一个参数(对象)是否是第二个参数(类及父类)的实例。

结果:
True
True
False
True
View Code

三.用科学的方法判断是函数还是方法

1.调用:from types import MethodType,FunctionType

from types import MethodType,FunctionType
def func(arg):
    """
    检查arg是方法还是函数
    :param arg:
    :return:
    """
    if isinstance(arg,MethodType):
        print('arg是一个方法')
    elif isinstance(arg,FunctionType):
        print('arg是一个函数')
    else:
        print('谁知道是啥玩意')
class Foo(object):

    def f1(self):
        pass

    def f2(self):
        pass

    def f3(self):
        pass

# obj = Foo()
# print(obj.f1)
# print(obj.f2)

obj = Foo()
Foo.f1(obj) # 把f1当做函数

obj = Foo()
obj.f1()    # 把f1当做方法,自动传self值
特点
class Foo(object):

    def f1(self):
        pass

    def f2(self):
        pass

    def f3(self):
        pass

    list_display = [f1,f2]

    def __init__(self):
        pass


for item in Foo.list_display:
    item(123)
练习,嘿嘿嘿
class Foo(object):

    def f1(self):
        pass

    def f2(self):
        pass

    def f3(self):
        pass

    list_display = [f1,f2]

obj = Foo()
Foo.list_display.append(obj.f3)

for item in Foo.list_display:
    print(item)
别慌,还有一个

 2.总结:

称谓:
 类.方法
 外.函数
到底是方法还是函数?
 对象.XXX  --> XXX就是方法
 类.XXX  --> XXX就是函数
 XXX  --> XXX就是函数
打印查看:
 function  --> 函数
 method  -->方法

四.反射

根据字符串为参数(第二个参数),去对象(第一个参数)中寻找与之同名的成员

1.记住

getattr # 根据字符串的形式,去对象中找成员。
hasattr # 根据字符串的形式,去判断对象中是否有成员。
setattr # 根据字符串的形式,动态的设置一个成员(内存)
delattr # 根据字符串的形式,动态的删除一个成员(内存)

 2.示例一(模块和包)

from types import FunctionType
import handler

while True:
    print("""
    系统支持的函数有:
        0. f0
        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中不存在输入的属性名')

    # 正确方式
    """
    if val == 'f1':
        handler.f1()
    elif val == 'f2':
        handler.f2()
    elif val == 'f3':
        handler.f3()
    elif val == 'f4':
        handler.f4()
    elif val == 'f5':
        handler.f5()
    """
示例一:

3.示例二(类)

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()
示例二

 4.反射补充

"""
getattr # 根据字符串的形式,去对象中找成员。
hasattr # 根据字符串的形式,去判断对象中是否有成员。
setattr # 根据字符串的形式,去判断对象动态的设置一个成员(内存)
delattr # 根据字符串的形式,去判断对象动态的设置一个成员(内存)
"""

import xx

# getattr
v1 = getattr(xx,'x1')
v2 = getattr(xx,'f1')
v2('杨森')

# hasattr
v3 = hasattr(xx,'x1')
v4 = hasattr(xx,'f1')
v4 = hasattr(xx,'f1')
v5 = hasattr(xx,'xxxxxxx')
print(v3,v4,v5)

# setattr
setattr(xx,'x2',999)
v6 = getattr(xx,'x2')
print(v6)

setattr(xx,'f2',lambda x:x+1)
v7 = getattr(xx,'f2')
v8 = v7(1)
print(v8)

# delattr
delattr(xx,'x1')
v9 = getattr(xx,'x1')
print(v9)
反射(模块和包,函数)
"""
getattr # 根据字符串的形式,去对象中找成员。
hasattr # 根据字符串的形式,去判断对象中是否有成员。
setattr # 根据字符串的形式,去判断对象动态的设置一个成员(内存)
delattr # 根据字符串的形式,去判断对象动态的设置一个成员(内存)
"""

class Foo(object):

    def __init__(self,a1):
        self.a1 = a1
        self.a2 = None

obj = Foo(1)

v1 = getattr(obj,'a1')
print(v1)

setattr(obj,'a2',2)

v2 = getattr(obj,'a2')
print(v2)
反射(类)

五. 小知识点补充

callable:可以检查一个对象是否是可以调用的

你见过什么后面可以加()?

  >>>类()

  >>>对象()

  >>>函数()

  >>>方法()

  以上所有都可以被调用.

def func():
    pass


class Foo(object):
    def __call__(self, *args, **kwargs):
        pass
    def func(self):
        pass
obj = Foo()


print(callable(func))
print(callable(Foo))
print(callable(obj))
print(callable(obj.func))
示例

猜你喜欢

转载自www.cnblogs.com/rixian/p/9562848.html
今日推荐