Python23_ object-oriented

Object-Oriented

ps: No matter what language, object-oriented three elements are: a package (with the class variables and functions encapsulate), inheritance, polymorphism

Object-oriented (OO, object-oriented) is a way of thinking to write code: program is what constitutes. Object-Oriented Programming: OOP (object-oriented programming)

Class, in fact, is an abstraction. The so-called abstract, that is the thing with the same characteristics are classified. For example User class, the abstract user information together

Properties and methods of classes.

Properties: it shows the characteristics of the class

Methods (behavior): specifies the functional class

Ps: conventions, classes with hump structure, and the first letter capitalized

Program (class) = data structure (attributes) + algorithms (methods, acts)

Object-oriented is to map the real world to the world of process procedures

Specific classes: Example

self: the current object (caller of the method)
CLS: the object's class
Note: either self or cls, just a variable name only, accustomed to the use of these two names, you can also use a different name (currently learning has not official explanations, personal understanding: an instance method of the first parameter represents the instance of the object itself, the first parameter represents the class class method in itself)

python which have a default constructor parameters can not

The method defined in class function call which

class Cat:
    #__new__方法分配内存,单例模式时会用到此方法
    def __new__(cls, *args, **kwargs):	#new方法为什么需要这些参数?此处这样写只是为了可以接受任何形式与数目的参数,在new里面一般并用不到,但是执行了new之后会自动调用init方法,那时会用到这些参数。亦即:*args与**kwargs并不是必要的格式。比如,在init方法中,如果需要的是除了self之外的一个参数(如name),那么此处也可以只声明一个变量接受该参数即可
        print("__new__")
        return super().__new__(cls)		#也可以:return = object.__new__(cls) 另,此处以本人目前的知识猜测,在object类中应是用了@property修饰了__new__()方法的,所以此处如果用object可以不加括号。加了括号也是一样的
        #注意:__new__方法必须要有返回值,返回实例化出来的实例,可以返回父类__new__返回代实例(此处采用的方法),也可以直接将object的__new__出来的实例返回
    #构造方法,该方法会创建对象(实例),自动调用
    def __init__(self, color, name):
        #前后有双下划线的方法由程序自动调用
        self.color = color
        self.name = name        
    def catch_mouse(self):
        print(self.name + " 正在抓老鼠")
    def __del__(self):
    	print("对象空间已经被释放")	#当对象的空间被释放的时候(引用对象的个数为0的时候)会自动调用此方法
    #ps:对象的引用个数可以用`import sys \n sys.getrefcount(Object)`来获取,比实际的对象多1,如果该对象空间已经被释放,则会报错

#创建实例 
tom = Cat("Blue","Tom")

print(tom.name)

Examples of process objects:

  1. Allocate a memory (__new __ ()), this method will be used when a single design pattern. When a new block of space, and then automatically calls the init method, the new method at this time will be automatically passed to the received parameter init method. The new space is passed to the init method of self references
  2. Initialization value (the __init __ ())

__new__()方法的注意事项:__new__方法必须要有返回值,返回实例化出来的实例,可以返回父类__new__返回代实例(此处采用的方法),也可以直接将object的__new__出来的实例返回

Properties privatization:
3. XX: single set before underline privatization property or method, can be used directly in the module, but prohibited from somemodule import * import, classes and subclasses can access the object
4. When the properties named in front plus "__", that is two underscores, it is grammar rules.
S: XX
, underlined single post, for avoiding conflicts with Python keyword
for private property or private method, which is also used in the class must be added __, i.e., double underline

Why can double underline privatization (hidden variables):
__dict__: any object has this property, which is filled with all the properties of the instance. Beginning with a double underscore attribute, the name will be converted: _ __ + class name attribute name, this time by 对象名._类名__属性名accessing

How to access private property: by method

class Student:
    """
    学生类
    """
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def set_name(self, name):
        if not len(name) < 3:
            self.__name = name

    def get_name(self):
        return self.__name
        
    #标注,默认是get的。@就是一个标记,比如下面的@age.setter,当用“=”时,就调用该函数。如果是用的".",就调用此方法
    @property   #@语法糖,前面加这个的可以像使用属性一样使用方法,即不用加括号
    def age(self):
        return self.__age
        
    #使用了@后方法名必须与属性名一致
        
    @age.setter #让方法可以像属性一样使用
    def age(self,age):
        self.__age = age


tom = Student("tom", 23)
print(tom.get_name())
tom.set_name("jack")
print(tom.get_name())

tom.hight = 23	#为tom额外添加hiht属性。

print(tom.age)  #可直接获得年龄,其实tom.age是在调用方法

tom.age = 18    #使用语法糖的方式更改属性值
print(tom.age)  #这里也使用了语法糖,实际上是调用的age方法


#输出:
tom
jack
23
18

The second approach on the use of property

class A(object):
    def __init__(self):
        self.__num = 10

    def set_num(self,num):
        self.__num = num
    def get_num(self):
        return self.__num

    num = property(get_num,set_num)	#这里的方法名可以任意取,则当使用=进行赋值操作时,相当调用第二个方法(设置值的方法),当仅仅是取值的时候,则调用第一个方法(取值的方法),等号前面的变量名必须与属性的变量名一致,但是不用加双下划线

obj = A()

print(obj.num)
obj.num = 15
print(obj.num)
	

Object class itself is
typically: To operate the class attribute, a class method; for instance when the object to operate, Examples of the method
self property name: instance attributes.

class User:
    # 在类里面定义的属性称为类属性,由所有实例共享。一般不在这里面写东西。
    num = 0

    def __init__(self, name):
        self.__name = name
        User.num += 1

    def print_name(self):
        print(self.__name)
        print(User.num)

    @property
    def name(self):
        return self.__name

    @classmethod  # 标注,表明这是类方法。即可以通过类名调用,必须用一个cls参数,cls就是类本身,与对象的self相当。
    def creat_user(cls, name, age):  # cls其实就是类本身
        user = cls(name)
        user.age = age
        return user

    @staticmethod  # 静态方法,可以直接通过类名调用。当一个方法即和类没有关系又和对象没有关系时,就用静态方法,就不用cls和self参数
    def sum(a, b):
        return a + b

    def __str__(self):  #当print对象的时候会调用这个方法。这个方法必须返回一个字符串
        _str = ""
        for k,v in self.__dict__.items():
            _str += str(k)
            _str += ":"
            _str += str(v)+" "
        return  _str



u = User("zhangsan")
u1 = User("lisi")
u.print_name()
u1.print_name()
User.num += 1
print(User.num)

u2 = User.creat_user("wangwu", 20)
# @classmethod修饰的方法是类方法,类方法可以通过类名调用。类方法必须有一个参数,cls,即类本身
print(u2.name)
print(User.sum(1, 3))	#通过类名调用静态方法
print(u.sum(2,4))	#通过实例对象调用静态方法
print(u1.sum(1,3))
u3 = u1.creat_user("laoli",50)
print(u3.name)
print(u1)

inherit

python support multiple inheritance, succession and inheritance order related content (property inherited from the first class)

Subclass object can call the parent class's direct method, also has properties of the parent class

All classes will inherit the default object class

Note: private property and private methods of the parent class is not inherited (beginning with __'s) , but if private property is inherited method (not rewrite) visited private properties or methods of the parent class, the parent classes or private methods or let use this method

class A:
    def __init__(self):
        self.name = "A"
    def print_test(self):
        print("A"*10)

class B(object):	#ps:如果一个类没有继承任何类,建议写上object类,object类是所有类最终的父类,即:所有类都继承自object类
    def __init__(self):
        self.name = "B"
    def print_test(self):
        print("B"*10)

class C(A):		#A是C的父类,又称基类。C是A的子类,派生类。C继承自A
    def __init__(self):
        super().__init__()    #调用父类的初始化方法
        self.age = 20
class D(A,B):   #多继承,是按照顺序,比如此处有两个name,那么D就继承到了A的。
    def print_test(self):
        super().print_test()
        self.print_test()

c = C()
print(c.name)
print(c.age)
d = D()
print(d.name)
print(C.__mro__)	#mro中的顺序是由C3算法决定的
#上面这句会输出:(<class '__main__.C'>, <class '__main__.A'>, <class 'object'>),表明调用C类的对象的方法时,搜索的顺序,如果C没有该方法,就用A的,如果A还没有,就调用object类的(caution,object类是所有类的父类,因为这里A没有继承除了object类之外的类,所以是A中找不到就到object中去找,如果A继承了其他类,比如D类,则A中找不到就会到D中去查找。即查找顺序为:本类>父类(按继承的先后顺序,先继承的先用)>父类的父类
print(isinstance(d,A))  #判断一个对象是否是一个类的实例。输出True,子类的对象也是父类的实例
print(issubclass(D,A))  #判断一个类是否是另一个类的子类
#以上的顺序表明了查找属性的顺序(多继承的访问顺序),如果C本身有,就用C本身的,如果C本身没有,而A有,则用A的,再否则用B的

Ducks type

Just a few class has similar features or attributes, even if does not inherit from the same parent, can also be considered to belong to the same class. For example, the following Programer and Manager, although not inherit from the same parent, but it is clear that the staff, it is possible to deliberately similar definition for a method or property

class Programer:
    def dowork(self):
        print("编程")

class Manager:
    def dowork(self):
        print("管理")

p = Programer()
m = Manager()
p.dowork()
m.dowork()

#判断某一对象是否是一个类的实例
print(isinstance(p,Programer))

Rewrite

This is a method to rewrite the definition of the same name in the parent class and subclass method, after calling the method call is to own, rather than the parent class method.

class Animal:
    name = "狗"
    def eat(self):
        print("-----吃-----")
    def run(self):
        print("-----跑-----")

class Dog(Animal):
    def bark(self):
        print("-----汪汪叫-----")

class XiaoTian(Dog):
    def fly(self):
        print("-----fly-----")
    def bark(self)print("-----狂叫-----“)
    	#Dog.bark(self)	#通过父类的类名,并以self为参数,可以调用父类中被重写了的方法
    	super().bark()	#通过super().方法名(),可以也可以调用父类被重写的方法,此种方法不需要self参数


xt = XiaoTian()

xt.run()
xt.bark()
xt.eat()
print(xt.name)

Polymorphism

Definition: when the type definition and is not the same type of run-time, this time is called polymorphism. (Ps: C ++ and java vary widely in polymorphic, C ++ and Java, polymorphic, somewhat similar to the cast)

class Dog(object):
	def print_self(self):
		print("This is dog")
class XiaoTianQuan(Dog):
	def print_self(self):
		print("This is XiaoTianQuan")
def introduce(temp):
	temp.print_self()
dog1 = Dog()
dog2 = XiaoTianQuan()
introduce(dog1)
introduce(dog2)

#所谓多态,即写完程序后,只是知道它调用一个方法,但是不确定它究竟是调用基类的还是调用子类的,在真正执行的一刹那,才根据当前的对象是谁去决定调用哪个方法
#因为python是动态类型的语言,所以python中的多态体现得不态明显

Class attribute, attribute instance

#需求:用一个变量存储一个类创建了多少个对象
class Tool(object):
	#属性:定义在类之内,方法之外的属性称为类属性
	count = 0
	#方法
	def __init__(self, name):
		self.__name = name
		Tool.count += 1	#对于类属性,用类名进行访问(就像实例对象的属性通过实例对象的名字访问一样)
tool1 = Tool("铁锹")
tool2 = Tool("共兵铲")

注意:实际上程序并不是每创建一个对象就在该对象的空间内放一个方法,而是在该空间内多了一个属性(变量),该属性可以知道这个对象的class,即保存了该类的一个引用,然后在调用该方法时到该类中查找该方法。故而一个抽象的类实际上也占用了内存空间,亦即类在程序里面也是一个对象,这个对象称为类对象,通过类创建出来的对象称为实例对象,实例对象里面的属性称为实例属性,类里面的属性称为类属性。

CAUTION : an object instance attributes and related data, and the instance of the object and a further example is a property not shared. Belonging to the class attribute is an object of the class, and can be shared among a plurality of the same attribute class instance object. Class property in a class definition, can only be defined once, nothing to do with creating an instance of an object.

  • Examples Properties
    Properties __init__ method and subsequent properties and may create an object referred to by way of example instance attributes (eg: assuming no name attributes define the class initialization, and that subsequent: S.name = "Dog", by such the method attribute is created instance attribute, the attribute defined in the init method belong instance attribute)

Examples of methods, class methods, static methods

Note :实例方法中的第一参数为self只是大家都遵循的一个规则,同时,类方法中的第一个参数cls也只是大家都遵循的规则

class Game(object):
	#类属性
	num = 0
	#实例方法
	def __init__(self):
		self.name = "laowang"
		
	#在方法前加了@classmethod的都称为类方法
	@classmethod	#装饰器
	def add_num(cls):	#不同于实例方法中必须有self参数保存该对象(实例),cls就是用来保存类的引用的,是class的简写。
		cls.num = 100

= Game Game ()
# class method Game.add_num () can be called by the name of the class. You can also create out by this class object to call the class method (personal understanding: the class object instance is created, the class also, so the methods of this class can be called)
Print (Game.num)

Note : The actual development in the future, if you want to do it with class, through generic category; if you want to do with function through generic function. That class has a function with neither fish nor fowl

Singleton design pattern

class S:
    __instance = None
    def __new__(cls, *args, **kwargs):
        if S.__instance is None:	#类属性通过类名访问
            S.__instance = super().__new__(cls)   #因为自己重写了__new__方法(分配内存的),所以必须调用父类的__new__()以分配内存
        return S.__instance   #ps:也可以写成:return cls.__instance


s1 = S()
s2 = S()
print(id(s1),id(s2))    #会发现两个对象的内存地址相同,即他们是同一个对象


#拓展:只初始化一次对象
class S:
    __instance = None
    __init_flag = False
    def __new__(cls, *args, **kwargs):
        if S.__instance is None:	#类属性通过类名访问
            S.__instance = super().__new__(cls)   #因为自己重写了__new__方法(分配内存的),所以必须调用父类的__new__()以分配内存
        return S.__instance   #ps:也可以写成:return cls.__instance
    def __init__(self,name):
    	if Dog.__init_flag == False:
    		self.name = name
    		Dog.__init_flag = True

Guess you like

Origin blog.csdn.net/qq_34873298/article/details/90549781