Hi, i'm having some trouble using the built-in apply function. I want to take a string in an external definition then apply definitions on it which are in a class.

The code I have is:

global msgstr

def create_message(message, msgstr):
    if msgstr[0:3].upper() == 'CMD':
	return apply(message, (msgstr))
    elif msgstr[0:3].upper() == 'RSP':
	return apply(message, (msgstr))
    elif msgstr[0:3].upper() == 'IND':
	return apply(message, (msgstr))
    elif msgstr[0:3].upper() not in 'CMDRSPIND':
	print "Miscellaneous message has been found with details", msgstr
    else:
	pass


class message(object):

    def __init__(self, msgstr):
	self.msgstr = msgstr

    def getdetails(self):
	print "Type: ", msgstr[0:3]
	print "Date Stamp: ", msgstr[9:11],"/",msgstr[7:9],"/",msgstr[3:7]

I'm taking in a string, for example CMD20090114:1 which I want to apply the function getdetails on. I input:
teststr="CMD20090114:1"
m=create_message(message, teststr)
m.getdetails()
It returns an error saying global name 'msgstr' is not defined
Can someone tell me where I'm going wrong.
Thanks

Dani AI

Generated

The NameError came from referencing a bare msgstr inside the instance method instead of the instance attribute. As noted, store the incoming string on the instance (for example self.msgstr) and access it via self inside getdetails. apply() is unnecessary — construct the object directly — and ’s point about mixed indentation is a common source of runtime errors in Python, so check that too.

A few practical improvements beyond the immediate fix:

  • Use a Capitalized class name (PEP 8) and avoid globals; keep parsing/validation near the constructor or in a factory. See PEP 8 on class naming.
  • Validate the incoming string instead of relying on fragile slice indices; use a regex and convert the date substring to a real date object so downstream code is simpler.
  • If you have different classes for CMD/RSP/IND, use a small dispatch mapping keyed by the 3-letter prefix so the factory returns the correct subclass.

Example (robust, different from the original slices):

import re
from datetime import datetime

_msg_re = re.compile(r'^(?P<kind>[A-Z]{3})(?P<date>\d{8}):(?P<seq>\d+)$')

class Message(object):
    def __init__(self, raw):
        m = _msg_re.match(raw)
        if not m:
            raise ValueError('invalid message: %r' % raw)
        self.kind = m.group('kind')
        self.date = datetime.strptime(m.group('date'), '%Y%m%d').date()
        self.seq = int(m.group('seq'))

    def get_details(self):
        print('Type:', self.kind)
        print('Date Stamp:', self.date.isoformat())

Quick troubleshooting: mixed tabs/spaces cause odd failures; ensure you call the class (e.g., Message(raw)) rather than using apply()apply() was removed in Python 3 (see What’s New in Python 3). For parsing dates, datetime.strptime is a safer choice than manual slicing (see the datetime docs). References: PEP 8 — Class Names, What’s New in Python 3 — builtins, datetime.strptime.

Recommended Answers

All 3 Replies

Here is how you could write this

def create_message(message, msgstr):
    if msgstr[0:3].upper() == 'CMD':
	return message(msgstr)
    elif msgstr[0:3].upper() == 'RSP':
	return message(msgstr)
    elif msgstr[0:3].upper() == 'IND':
	return message(msgstr)
    elif msgstr[0:3].upper() not in 'CMDRSPIND':
	print "Miscellaneous message has been found with details", msgstr
    else:
	pass


class message(object):

    def __init__(self, msgstr):
	self.msgstr = msgstr

    def getdetails(self):
        msgstr = self.msgstr
	print "Type: ", msgstr[0:3]
	print "Date Stamp: ", msgstr[9:11],"/",msgstr[7:9],"/",msgstr[3:7]

In the method getdetails , you don't need to access a 'global' msgstr, you need to access the member msgstr of your message instance self. Also note that you never need the apply function. It's an old fashioned python syntax. Instead of apply(func, args) you can write func(*args) , where args is a tuple or a list. If it's an explicit tuple like in apply(func, (1, 2, 3)) , you can just write func(1, 2, 3) .

I haven't checked much, but I run error too. One thing, I see "message" in many places and don't know if it is class or variable
Anyway, my IDE complained of mixed indentation and here is corrected version

global msgstr

def create_message(message, msgstr):
    if msgstr[0:3].upper() == 'CMD':
        return apply(message, (msgstr))
    elif msgstr[0:3].upper() == 'RSP':
        return apply(message, (msgstr))
    elif msgstr[0:3].upper() == 'IND':
        return apply(message, (msgstr))
    elif msgstr[0:3].upper() not in 'CMDRSPIND':
        print "Miscellaneous message has been found with details", msgstr
    else:
        pass


class message(object):

    def __init__(self, msgstr):
        self.msgstr = msgstr

    def getdetails(self):
        print "Type: ", msgstr[0:3]
        print "Date Stamp: ", msgstr[9:11],"/",msgstr[7:9],"/",msgstr[3:7]

teststr="CMD20090114:1"
m=create_message(message, teststr)
m.getdetails()

Thanks for the help guys, all working now!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.