파이썬 반사 객체 지향, 메소드 비스

반사

개념은 처음 제안 된 1982 년에 스미스 반영 주로이 프로그램가 액세스 할 수에 자신의 상태 나 행동 (반성)을 감지하고 수정할 수있는 기능을 의미한다. 그것은 앞으로 빠르게 컴퓨터 과학 반사의 응용 프로그램에 조회 주도 개념 넣습니다. 먼저 언어 설계 프로그래밍 분야에서 사용하고, 리스프 객체 지향 측면에서 성과를 만들었다.

파이썬은 반사 객체 지향 : 객체 관련 속성이 문자열에 의해 운영. 모든 (반사를 사용할 수 있습니다) 파이썬의 객체이다

네 가지 기능을 달성 할 수 내성적

다음 방법은 클래스와 객체에 적용 할 수있다 (모든 것은 객체, 클래스 자체가 대상)

예시적인 객체 인스턴스화

class Foo:
    f = '类的静态变量'
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def say_hi(self):
        print('hi,%s'%self.name)

obj=Foo('egon',73)

#检测是否含有某属性
print(hasattr(obj,'name'))
print(hasattr(obj,'say_hi'))

#获取属性
n=getattr(obj,'name')
print(n)
func=getattr(obj,'say_hi')
func()

print(getattr(obj,'aaaaaaaa','不存在啊')) #报错

#设置属性
setattr(obj,'sb',True)
setattr(obj,'show_name',lambda self:self.name+'sb')
print(obj.__dict__)
print(obj.show_name(obj))

#删除属性
delattr(obj,'age')
delattr(obj,'show_name')
delattr(obj,'show_name111')#不存在,则报错

print(obj.__dict__)

물체의 반사

class Foo(object):
 
    staticField = "old boy"
 
    def __init__(self):
        self.name = 'wupeiqi'
 
    def func(self):
        return 'func'
 
    @staticmethod
    def bar():
        return 'bar'
 
print getattr(Foo, 'staticField')
print getattr(Foo, 'func')
print getattr(Foo, 'bar')

클래스의 반사

import sys

def s1():
    print 's1'

def s2():
    print 's2'

this_module = sys.modules[__name__]

hasattr(this_module, 's1')
getattr(this_module, 's2')

반사 현재 모듈

#一个模块中的代码
def test():
    print('from the test')
"""
程序目录:
    module_test.py
    index.py
 
当前文件:
    index.py
"""
# 另一个模块中的代码
import module_test as obj

#obj.test()

print(hasattr(obj,'test'))

getattr(obj,'test')()

다른 모듈의 광을 반사

응용 프로그램의 반사 :

반사의 네 가지 기능을 알아보세요. 그런 다음 사용은 그것이 무엇인지 결국 반사? 그 시나리오는 무엇입니다?

이제하자가 브라우저를 열고 웹 사이트를 방문, 로그온 할 로그인 화면으로 이동합니다, 당신 등등, 사실 실제로 링크 중 하나를 클릭하여 등록 점프 인터페이스를 등록하고 클릭하여 각 링크를 처리하는 기능이나 방법이있을 것이다.

class User:
    def login(self):
        print('欢迎来到登录页面')
    
    def register(self):
        print('欢迎来到注册页面')
    
    def save(self):
        print('欢迎来到存储页面')

while 1:
    choose = input('>>>').strip()
    if choose == 'login':
        obj = User()
        obj.login()
    
    elif choose == 'register':
        obj = User()
        obj.register()
        
    elif choose == 'save':
        obj = User()
        obj.save()

반사를 배울하지 않았다 이전 솔루션

class User:
    def login(self):
        print('欢迎来到登录页面')
    
    def register(self):
        print('欢迎来到注册页面')
    
    def save(self):
        print('欢迎来到存储页面')

user = User()
while 1:
    choose = input('>>>').strip()
    if hasattr(user,choose):
        func = getattr(user,choose)
        func()
    else:
        print('输入错误。。。。')

반사 솔루션을 공부 한 후

어떻게 간단한 눈.

II. 방법 대 기능

여기에 배운, 난 당신이 질문이되었을 수도 대답을 마지막으로 수 있었다. 즉, 우리가 결국 그것이라는 것입니다, 스트립 STR의 방법으로 말했다있는 기능 (혀의 슬립라는 방법)이다) (렌 호출 이전의 연구이다? 기능 및 방법의 차이점과 유사점은 무엇인가? 나는 공식적인 설명은 여기입니다.

2.1 함수 (방법)에 이름을 인쇄하여 판단

def func():
    pass

print(func)  # <function func at 0x00000260A2E690D0>


class A:
    def func(self):
        pass
    
print(A.func)  # <function A.func at 0x0000026E65AE9C80>
obj = A()
print(obj.func)  # <bound method A.func of <__main__.A object at 0x00000230BAD4C9E8>>
View Code

2.2 모듈 유형 검증

from types import FunctionType
from types import MethodType

def func():
    pass

class A:
    def func(self):
        pass

obj = A()

print(isinstance(func,FunctionType))  # True
print(isinstance(A.func,FunctionType))  # True
print(isinstance(obj.func,FunctionType))  # False
print(isinstance(obj.func,MethodType))  # True

2.3 정적 메소드의 함수

from types import FunctionType
from types import MethodType

class A:
    
    def func(self):
        pass
    
    @classmethod
    def func1(self):
        pass
    
    @staticmethod
    def func2(self):
        pass
obj = A()

# 静态方法其实是函数
# print(isinstance(A.func2,FunctionType))  # True
# print(isinstance(obj.func2,FunctionType))  # True

함수 및 방법 2.4 사이의 차이

상기의 기능 및 방법 외에도이 다른에 따라서, 우리는 다음과 같은 점 차이를 요약했다.

(1) 함수가 명시 적으로 데이터를 전달한다. 우리가 어떤 데이터를 전달 렌 () 함수로 표시 할 경우를 처리한다.

(2) 함수는 객체와는 아무 상관이있다.

데이터 (3) 방법은 암시 적으로 전송된다.

(4) 내부의 데이터 클래스를 동작시키는 방법.

(5) 방법은 객체와 연관된다. 우리가하고 전화 아니므로 우리는 문자열 s는, 다음 호출) (s.strip이 같은 스트립 () 메소드 str을 객체입니다. 예, 스트립 () 메소드는 객체 STR에 속한다.

둘 사이의 차이를 알고하는 기능과 방법,하지만 우리의 마음을 호출 할 때 아마도 우리는 느슨한 일상 구어체에있을 것입니다.

자바 방법 등의 다른 언어에서는 단지, C 유일한 기능은 C ++는,이 클래스 여부에 따라 달라집니다.

III. 비스 방법

정의 : 메서드 이름에 의해 제공되는 플러스를 두 번 밑줄 이름 밑줄 __ __ 방법을 냉각 통역 더블 다운은 특별한 방법으로는, 그의 방법은 특별한 의미이며, 방법은 우리가 파이썬 소스 프로그래머을 두 배로하는 것입니다 개발 방법을 두 배로 노력하지만 추가 연구 방법은 소스 코드를 읽고, 우리에게 더 이익을 두 배로하지 마십시오.

전화 : 초기화 : 같은 기관이 트리거처럼 무덤, 무의식적으로 두 아래 방법, 예를 들어, 트리거 할 때 다른 방법에서 두 번, 다른 트리거 모드가 있습니다

1.3 __len

class B:
    def __len__(self):
        print(666)

b = B()
len(b) # len 一个对象就会触发 __len__方法。

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

    def __len__(self):
        return len(self.__dict__)
a = A()
print(len(a))

3.02 __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))

3.03 STR

클래스가 __str__ 방법을 정의되면, 인쇄 대상, 방법은 기본 출력 값을 반환 할 때.

class A:
    def __init__(self):
        pass
    def __str__(self):
        return '太白'
a = A()
print(a)
print('%s' % a)

3.04에 repr

클래스가 __repr__ 방법, 다음에 repr에서 (객체)를 정의하면, 방법은 기본 출력 값을 반환합니다.

class A:
    def __init__(self):
        pass
    def __repr__(self):
        return '太白'
a = A()
print(repr(a))
print('%r'%a)

3.05 전화

개체 뒤에 괄호, 실행을 트리거합니다.

주 : 생성자가 __new__ 의해 실행되는 개체, 즉 생성하도록 트리거된다; () (객체 () 또는 클래스 클래스 이름 = 오브젝트 () 호출이 객체의 방법에 의해 행해진 다 대한 즉 브래킷 트리거 )

class Foo:

    def __init__(self):
        pass    
    def __call__(self, *args, **kwargs):
        print('__call__')

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

3.06 __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)

의 3.07

객체가 상기 메모리에 놓을 때 소멸자, 자동 실행을 트리거링.

참고 : 파이썬은 높은 수준의 언어이기 때문에이 작업이 실행 파이썬 인터프리터에 있기 때문에이 방법은 정의 할 필요가 우려없이 사용 프로그래머가 메모리를 할당하고 해제, 일반적으로, 그래서 소멸자가 호출 자동 트리거 인터프리터에 의해 시간 가비지 수집기에서 수행.

3.08__new

class A:
    def __init__(self):
        self.x = 1
        print('in init function')
    def __new__(cls, *args, **kwargs):
        print('in new function')
        return object.__new__(A, *args, **kwargs)

a = A()
print(a.x)
class A:
    __instance = None
    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            obj = object.__new__(cls)
            cls.__instance = obj
        return cls.__instance

싱글

싱글 특정 분석

싱글 톤 패턴은 일반적인 소프트웨어 디자인 패턴이다. 핵심 구조에서 단지 하나의 실시 예는 특정 클래스 카테고리 포함 칭한다. 예 인스턴스의 수의 시스템 자원 저장 제어를 용이하게하도록, 단일 모드 시스템을 클래스 인스턴스 및 외부로 쉽게 접근 할 단 하나 개의 인스턴스를 보장합니다. 당신은 단지 하나가 될 수있는 시스템의 객체 클래스를 원하는 경우, 싱글 톤 패턴은 최적의 솔루션입니다.
[싱글의 경우 모델의 동기, 이유]
작업하는 시스템의 특정 유형은 하나의 인스턴스는, 예를 들어, 시스템은 다수의 인쇄 작업을 포함 할 수 있지만 직업을 가질 수 있습니다 중요하다 시스템 만 당신은 창 관리자 또는 파일 시스템을 가질 수있는 시스템이 타이밍 장치 또는 ID (번호) 생성기를 할 수 있습니다. 윈도우에서, 당신은 단지 작업 관리자를 열 수 있습니다. 당신이 유일하게 윈도우 객체의 메커니즘을 사용하지 않는 경우이 윈도우의 내용이 정확히 같은 표시 할 경우, 여러 개의 창은 중복 개체, 메모리 자원의 낭비, 팝업, 일치하지 않는 내용을 윈도우가 표시되면, 그것은 순간에 그 의미 시스템이 실제와 일치 여러 상태를 가지고, 오해는, 사용자에게 가져올 것 하나는 실제 상태이다 모른다. 그래서 때로는 시스템은 클래스 하나의 인스턴스 만 매우 중요하다 개체의 고유성을 보장합니다.
어떻게 클래스의 하나 개의 인스턴스를 확인하고,이 경우는 접근이 용이? 객체가 언제든지 액세스 할 수 있지만, 우리는 여러 개체의 인스턴스를 방지 할 수 있는지 될 수있는 전역 변수를 정의합니다. 더 나은 솔루션을 저장을 담당하는 클래스 자체의 유일한 인스턴스를하도록하는 것입니다. 이 클래스는 다른 인스턴스가 생성되지 않도록 수 있으며, 인스턴스에 액세스하는 방법을 제공 할 수있다. 이 동기 모드 싱글 톤 패턴이다.
[싱글] 장점과 단점
[장점]
먼저, 컨트롤 인스턴스
의 모든 개체는 고유 한 인스턴스에 액세스 할 수 있도록하기 때문에 같은 다른 객체는 자신의 싱글 객체의 복사본을 하나의 인스턴스를 방지 할 수 있습니다 싱글 패턴.
둘째, 유연성
제어 클래스의 인스턴스 과정 때문에, 유연성이 클래스 인스턴스화 프로세스를 변경할 수 있도록.
[단점]
첫째, 오버 헤드
수의 몇 가지 있지만,하지만 여전히 일부 오버 헤드를 필요로 모든 객체 요청 참조하는 경우 클래스의 인스턴스가 있는지 확인합니다. 초기화 정적을 사용하여이 문제를 해결할 수 있습니다.
둘째, 혼란의 가능한 개발
싱글 객체 (클래스 라이브러리에 정의 특히 객체)를 사용하여, 개발자들은 객체의 인스턴스를 새로운 키워드를 사용할 수 없다는 것을 명심해야합니다. 당신이 라이브러리 소스 코드에 액세스 할 수 있기 때문에 응용 프로그램 개발자가 예기치 않게 자신을 발견 할 수 있도록 직접 인스턴스화 할 수 없습니다.
셋째, 개체 수명은
문제가 하나의 개체를 삭제할 해결할 수 없습니다. (닷넷 프레임 워크의 언어에 따라, 예를 들어,)의 메모리 관리를 제공하는 언어, 그것은 전용 인스턴스에 대한 참조를 포함하고 있기 때문에 단지 클래스 형태의 단일 인스턴스가 할당되지 초래할 수있다. 일부 언어 (예를 들어, C ++)에서, 다른 클래스의 인스턴스 개체가 삭제 될 수 있지만,이 참조의 중단으로 이어질 것 싱글을 표시

3.09 __item__ 시리즈

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__)

3.10 관련 콘텍스트 관리자

enter __exit

# 如果想要对一个类的对象进行with  as 的操作 不行。
class A:
    def __init__(self, text):
        self.text = text

with A('大爷') as f1:
    print(f1.text)

그들은 이런 식으로 작동하지 않았다

class A:
    
    def __init__(self, text):
        self.text = text
    
    def __enter__(self):  # 开启上下文管理器对象时触发此方法
        self.text = self.text + '您来啦'
        return self  # 将实例化的对象返回f1
    
    def __exit__(self, exc_type, exc_val, exc_tb):  # 执行完上下文管理器对象f1时触发此方法
        self.text = self.text + '这就走啦'
        
with A('大爷') as f1:
    print(f1.text)
print(f1.text)

그들은이있다 할 수있다

class Diycontextor:
    def __init__(self,name,mode):
        self.name = name
        self.mode = mode
 
    def __enter__(self):
        print "Hi enter here!!"
        self.filehander = open(self.name,self.mode)
        return self.filehander
 
    def __exit__(self,*para):
        print "Hi exit here"
        self.filehander.close()
 
 
with Diycontextor('py_ana.py','r') as f:
    for i in f:
        print i

사용자 정의 파일 관리자

관련 인터뷰 질문 :

class StarkConfig:
    def __init__(self,num):
        self.num = num
    
    def run(self):
        self()
    
    def __call__(self, *args, **kwargs):
        print(self.num)

class RoleConfig(StarkConfig):
    def __call__(self, *args, **kwargs):
        print(345)
    def __getitem__(self, item):
        return self.num[item]

v1 = RoleConfig('alex')
v2 = StarkConfig('太白金星')
# print(v1[1])
# print(v2[2])
v1.run()

-------
class UserInfo:
    pass


class Department:
    pass


class StarkConfig:
    def __init__(self, num):
        self.num = num
    
    def changelist(self, request):
        print(self.num, request)
    
    def run(self):
        self.changelist(999)


class RoleConfig(StarkConfig):
    def changelist(self, request):
        print(666, self.num)


class AdminSite:
    
    def __init__(self):
        self._registry = {}
    
    def register(self, k, v):
        self._registry[k] = v


site = AdminSite()
site.register(UserInfo, StarkConfig)
# 1 
# obj = site._registry[UserInfo]()

# 2
obj = site._registry[UserInfo](100)
obj.run()

-------
class UserInfo:
    pass

class Department:
    pass

class StarkConfig:
    def __init__(self,num):
        self.num = num

    def changelist(self,request):
        print(self.num,request)

    def run(self):
        self.changelist(999)

class RoleConfig(StarkConfig):
    def changelist(self,request):
        print(666,self.num)


class AdminSite:

    def __init__(self):
        self._registry = {}

    def register(self,k,v):
        self._registry[k] = v(k)

site = AdminSite()
site.register(UserInfo,StarkConfig)
site.register(Department,RoleConfig)

for k,row in site._registry.items():
    row.run()

-------
class A:
    list_display = []
    
    def get_list(self):
        self.list_display.insert(0,33)
        return self.list_display

s1 = A()
print(s1.get_list())

-------
class A:
    list_display = [1, 2, 3]
    def __init__(self):
        self.list_display = []
    def get_list(self):
        self.list_display.insert(0, 33)
        return self.list_display


s1 = A()
print(s1.get_list())

------
class A:
    list_display = []

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

class B(A):
    list_display = [11,22]


s1 = A()
s2 = B()
print(s1.get_list())
print(s2.get_list())

추천

출처www.cnblogs.com/xxpythonxx/p/12623312.html